Skip to content

Persisted connection catalogs keep model ids that the snapshot has retired #3354

Description

@Astro-Han

When a models.dev refresh removes a model id from a provider's fallback list, existing users keep it. ensureConnection (packages/runtime-host/src/server/bootstrap-runtime-policy.ts) returns an existing connection unchanged, so enabledModelIds is never reconciled against the current registry. A persisted default target stays valid while the old id is still enabled (packages/storage/src/runtime-policy/connection-catalog-document.ts), and Host admission trusts the persisted models[] row (packages/runtime-host/src/server/connection-model-admission.ts). The id is still shown as available and default-capable, and still admitted for execution, after the provider has retired it.

Providers with modelDiscovery: { kind: 'protocol' } self-heal on the next successful discovery. Two cases do not:

  • opencode-free is { kind: 'fallback' } — its own reason string states the anonymous endpoint has no model-list contract, so no discovery pass ever repairs the state.
  • google preserves the old catalog when discovery fails.

Why this is not tied to one refresh

This is standing behaviour, not a regression. #2050 removed hy3-free from the same OpenCode Free list for the same reason — an upstream deprecation — and touched no persistence: git show 41a983804 --name-only matches zero files under packages/storage/ or packages/runtime-host/. There is no model-catalog migration or tombstone mechanism; the tombstones in sqlite-session-metadata-store.ts serve session metadata only.

Reverting a refresh does not fix it either: the ids return to the fallback lists but remain retired upstream, so a persisted default still fails at call time.

Scope

A targeted upgrade migration that, for providers without a self-healing discovery contract, removes retired ids from persisted inventories and enabled sets and clears or repairs a matching default target, with base-state upgrade tests.

Found during review of #3324 by @hqhq1025.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions