Falling back to the bundled model catalog is completely silent (exit 0, empty stderr, 0-byte log)

Open Beginner friendly
#1,187 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
typescript
Domain
cli

Research direction

Start in packages/opencode/src/provider/models.ts at the lazy Data() loader, especially the bundled snapshot return and the non-2xx fetch path. Re-run the isolated HOME/XDG reproduction with the closed models.dev port, then verify that fallback use produces a warn-level diagnostic while the command still returns the bundled model list.

Written by the indexing model from the issue text.

Description

Summary

When the models.dev fetch is slow or unreachable, the CLI falls back to the bundled snapshot and reports nothing: exit 0, empty stderr, and a 0-byte log file. The user gets a months-old model catalog with no signal that anything degraded, and because no cache is written the same thing happens on the next invocation.

This is a startup race, not a permanent short-circuit. On a fast connection the fetch wins and live models appear, so the failure is intermittent and environment-dependent — which is exactly what makes the silence expensive to debug.

Reproduction

Shipped @altimateai/altimate-code 0.9.7 binary, driven through an isolated HOME + XDG dirs so the real cache is never touched, with models.dev pointed at a closed port:

env HOME=$h XDG_CACHE_HOME=$h/.cache XDG_DATA_HOME=$h/.local/share \
    XDG_CONFIG_HOME=$h/.config XDG_STATE_HOME=$h/.local/state \
    OPENCODE_MODELS_URL=http://127.0.0.1:9 OPENAI_API_KEY=dummy \
    altimate-code models

Result:

EXIT=0  elapsed=2s
stdout lines: 91
stderr bytes: 0
models.json cached: 0
log file: 0 bytes  (.local/share/altimate-code/log/opencode.log)

The 91 listed models are the bundled snapshot. Its openai set includes gpt-5-codex, gpt-5.1-codex, gpt-5.1-codex-max, gpt-5.1-codex-mini, codex-mini-latest — all removed from models.dev — and is missing gpt-5.5 and every gpt-5.6 variant.

The same silent outcome was measured with models.dev artificially delayed 5s: the process exits at ~1.9s having served the snapshot, the request is made but the bytes never arrive, nothing is cached, and the next short command races again.

Cause

packages/opencode/src/provider/models.ts:

export const Data = lazy(async () => {
  const cached: unknown = await Filesystem.readJson(...).catch(() => {})
  if (isCatalog(cached)) return cached
  const snapshot = await import("./models-snapshot.js").then(...).catch(() => undefined)
  if (snapshot) return snapshot            // <-- no log, no warning
  if (Flag.OPENCODE_DISABLE_MODELS_FETCH) return {}
  return Flock.withLock(...)
})

The if (snapshot) return snapshot branch carries no logging at all. The non-2xx branch a few lines down is likewise silent:

if (!result2.ok) return {}

Both log.error calls that do exist ("models.dev body is not a catalog", "Failed to fetch models.dev") sit on paths that a lost race never reaches, because the process exits before the fetch resolves.

Suggested direction (not implemented here)

A single log line at warn when Data() falls through to the bundled snapshot would make this diagnosable, ideally carrying the snapshot's age so "your catalog is five months old" is visible rather than inferred. Whether short-lived commands should also wait briefly for the fetch, or surface a hint on the models command specifically, is a separate design question.

Related

The staleness of the snapshot this path falls back to is tracked in #1186. That issue is about what gets embedded; this one is about not being told you are on the fallback. Fixing #1186 shrinks the blast radius here but does not remove the silence.

Dominant language
TypeScript
Stars
813
Forks
134
Avg merge
2d 5h
Merged PRs (30d)
62

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from AltimateAI/altimate-code

All issues in AltimateAI/altimate-code

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.