Summary
Every shipped release binary embeds a checked-in test fixture as its bundled models.dev catalog, not a live one. The newest entry in that fixture is 2026-03-30 — roughly five months stale.
.github/workflows/release.yml builds each platform binary with:
- name: Build ${{ matrix.name }}
run: bun run packages/opencode/script/build.ts --target-index=${{ matrix.index }}
env:
...
MODELS_DEV_API_JSON: test/tool/fixtures/models-api.json
packages/opencode/script/build.ts does process.chdir(packages/opencode) before reading that path, so it resolves to packages/opencode/test/tool/fixtures/models-api.json, and:
const modelsData = process.env.MODELS_DEV_API_JSON
? await Bun.file(process.env.MODELS_DEV_API_JSON).text()
: await fetch(`${modelsUrl}/api.json`).then((x) => x.text())
await Bun.write(path.join(dir, "src/provider/models-snapshot.ts"), ...)
So the env var short-circuits the live fetch and the fixture is written over src/provider/models-snapshot.ts, which is then compiled into the binary.
Evidence
Measured against the checked-in fixture and the live catalog on 2026-08-29:
| artefact |
providers |
openai models |
newest release_date |
test/tool/fixtures/models-api.json (what ships) |
105 |
47 |
2026-03-30 |
src/provider/models-snapshot.ts (committed blob, dev builds only) |
144 |
51 |
2026-06-22 |
live https://models.dev/api.json |
207 |
47 |
2026-08-29 |
The fixture carries no gpt-5.5 and no gpt-5.6 family at all, and it still carries five OpenAI models that were shut down on 2026-07-23 (gpt-5-codex, gpt-5.1-codex, gpt-5.1-codex-max, gpt-5.1-codex-mini, gpt-5.2-codex — deleted from models.dev in sst/models.dev#3707). It is also missing 102 providers relative to live, so this is not an OpenAI-specific problem.
Note that the committed models-snapshot.ts blob is fresher than the fixture, and is what a local bun run build produces — so the artefact developers test against is not the artefact users get.
Why this is wrong
Upstream's release workflow (.github/workflows/publish.yml, build-cli → Build) sets only OPENCODE_VERSION, OPENCODE_RELEASE, GH_REPO, GH_TOKEN. It does not set MODELS_DEV_API_JSON, so upstream release binaries embed a catalog fetched at release time. The override is a fork-only deviation.
git log -S MODELS_DEV_API_JSON -- .github/workflows/release.yml returns a single commit, f2cd5c1245 (the initial fork commit). It appears to be copy-paste from the CI job, where a hermetic build genuinely is correct, and there is no comment explaining it.
Impact
The bundled snapshot is the fallback whenever the runtime models.dev fetch has not yet populated ~/.cache/.../models.json — a fresh install, an offline machine, or a slow link. In that state users see a catalog five months old: no gpt-5.5, no gpt-5.6, and several models that no longer serve traffic.
Fix
Remove the MODELS_DEV_API_JSON line from the Build step in release.yml only, keeping it in ci.yml and pre-release-check.ts where hermetic builds are correct. This makes release builds depend on models.dev at build time, so the fetch also needs a guard that fails the build loudly rather than embedding an empty or error-body catalog.
Scope
This issue is only about what gets embedded at release time. The separate runtime problem — that falling back to the bundled snapshot produces no log line, no stderr, and exit 0 — is tracked separately.
Summary
Every shipped release binary embeds a checked-in test fixture as its bundled models.dev catalog, not a live one. The newest entry in that fixture is 2026-03-30 — roughly five months stale.
.github/workflows/release.ymlbuilds each platform binary with:packages/opencode/script/build.tsdoesprocess.chdir(packages/opencode)before reading that path, so it resolves topackages/opencode/test/tool/fixtures/models-api.json, and:So the env var short-circuits the live fetch and the fixture is written over
src/provider/models-snapshot.ts, which is then compiled into the binary.Evidence
Measured against the checked-in fixture and the live catalog on 2026-08-29:
release_datetest/tool/fixtures/models-api.json(what ships)src/provider/models-snapshot.ts(committed blob, dev builds only)https://models.dev/api.jsonThe fixture carries no
gpt-5.5and nogpt-5.6family at all, and it still carries five OpenAI models that were shut down on 2026-07-23 (gpt-5-codex,gpt-5.1-codex,gpt-5.1-codex-max,gpt-5.1-codex-mini,gpt-5.2-codex— deleted from models.dev in sst/models.dev#3707). It is also missing 102 providers relative to live, so this is not an OpenAI-specific problem.Note that the committed
models-snapshot.tsblob is fresher than the fixture, and is what a localbun run buildproduces — so the artefact developers test against is not the artefact users get.Why this is wrong
Upstream's release workflow (
.github/workflows/publish.yml,build-cli→Build) sets onlyOPENCODE_VERSION,OPENCODE_RELEASE,GH_REPO,GH_TOKEN. It does not setMODELS_DEV_API_JSON, so upstream release binaries embed a catalog fetched at release time. The override is a fork-only deviation.git log -S MODELS_DEV_API_JSON -- .github/workflows/release.ymlreturns a single commit,f2cd5c1245(the initial fork commit). It appears to be copy-paste from the CI job, where a hermetic build genuinely is correct, and there is no comment explaining it.Impact
The bundled snapshot is the fallback whenever the runtime models.dev fetch has not yet populated
~/.cache/.../models.json— a fresh install, an offline machine, or a slow link. In that state users see a catalog five months old: nogpt-5.5, nogpt-5.6, and several models that no longer serve traffic.Fix
Remove the
MODELS_DEV_API_JSONline from theBuildstep inrelease.ymlonly, keeping it inci.ymlandpre-release-check.tswhere hermetic builds are correct. This makes release builds depend on models.dev at build time, so the fetch also needs a guard that fails the build loudly rather than embedding an empty or error-body catalog.Scope
This issue is only about what gets embedded at release time. The separate runtime problem — that falling back to the bundled snapshot produces no log line, no stderr, and exit 0 — is tracked separately.