You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A partial legacy provider.<id>.models.<id> capability override resets the fields it omits. migrateModel fills those fields with global defaults before the config provider can inherit the existing catalog values.
For example, overriding only input modalities can turn tools on and replace audio output with text. Native V2 partial overrides already preserve those fields after #51365. #45760 fixed defaults for new models; this is the remaining inheritance case for existing models.
Plugins
None required; reproduced through the core config-provider test fixture.
OpenCode version
V2 source at 0a46301e36d7edd517dd89736acc5daf9c74898e. The same migration code is still present at 30f411945953f6de79a87b3b35e9f706bb2e9839.
Steps to reproduce
Seed the catalog fixture's custom/chat model with { tools: false, input: ["audio"], output: ["audio"] }.
Normalize and apply this legacy config through ConfigProviderPlugin:
The same problem affects output-only, tool-call-only, and empty-input overrides.
Screenshot and/or share link
Minimal patch and four regression cases. On the source base above, the four regressions failed before the fix; the focused provider/normalization suites passed afterward (59 tests, 413 assertions). This is not a full-suite pass.
The patch leaves omitted fields unset so the existing Model.mergeCapabilities logic handles inheritance and new-model defaults.
Thanks for the detailed report and the patch. I can reproduce this on the latest dev (f930aa8a).
I seeded the catalog model custom/chat with { tools: false, input: ["audio"], output: ["audio"] }, normalized a legacy provider.custom.models.chat override and applied it through ConfigProviderPlugin. Each partial override reset the fields it didn't set to the global defaults:
The cause looks like migrateModel in packages/core/src/v1/config/migrate.ts, which fills omitted capability fields with Model.Capabilities.default() before Model.mergeCapabilities can fall back to the catalog values. The test file below reproduces it; place it in packages/core/test/config/ to run it.
Activity
opencodejr commentedon Oct 27, 2026
Thanks for the detailed report and the patch. I can reproduce this on the latest
dev(f930aa8a).I seeded the catalog model
custom/chatwith{ tools: false, input: ["audio"], output: ["audio"] }, normalized a legacyprovider.custom.models.chatoverride and applied it throughConfigProviderPlugin. Each partial override reset the fields it didn't set to the global defaults:modalities.input: ["text","image"]→{ tools: true, input: ["text","image"], output: ["text"] }modalities.output: ["text"]→toolsandinputreset totrue/["text","image"]tool_call: true→inputandoutputreset to["text","image"]/["text"]modalities.input: []→tools: true,output: ["text"]The cause looks like
migrateModelinpackages/core/src/v1/config/migrate.ts, which fills omitted capability fields withModel.Capabilities.default()beforeModel.mergeCapabilitiescan fall back to the catalog values. The test file below reproduces it; place it inpackages/core/test/config/to run it.Reproduction script (repro-53280.test.ts)
Run it:
bun repro-53280.test.ts