Repository navigation
Description
Observation
OpenCode loads custom providers only when their ID exactly matches a key in the CUSTOM_LOADERS dictionary in packages/opencode/src/provider/provider.ts. If you want two Vertex AI instances in one session, one pinned to europe-west4 and another pinned to the eu multi-region, declaring two provider entries with distinct IDs doesn't work. Only the canonical google-vertex ID triggers the Vertex-specific loader.
Reproduction
opencode.json:
{
"provider": {
"google-vertex": {
"options": { "project": "P", "location": "europe-west4" },
"models": { "gemini-2.5-pro": {} }
},
"google-vertex-eu": {
"npm": "@ai-sdk/google-vertex",
"options": {
"project": "P",
"location": "eu",
"baseURL": "https://aiplatform.eu.rep.googleapis.com/v1/projects/P/locations/eu/publishers/google"
},
"models": { "gemini-3.5-flash": {} }
}
},
"enabled_providers": ["google-vertex", "google-vertex-eu"]
}Run:
opencode run --model google-vertex-eu/gemini-3.5-flash "ping"
Result:
Error: Model not found: google-vertex-eu/gemini-3.5-flash.
Error: {
"name": "UnknownError",
"data": { "message": "Unexpected server error. Check server logs for details." }
}
The same model on google-vertex/gemini-3.5-flash (canonical ID) works.
Where the behaviour comes from
packages/opencode/src/provider/provider.ts:1320-1337: the custom-loader iteration walksObject.entries(custom(dep)), i.e. the canonical loader keys only. A custom-IDed entry never enters this loop.packages/opencode/src/provider/provider.ts:450-494: thegoogle-vertexloader is where ADC token acquisition and theAuthorization-injectingfetchhandler get wired intooptions.fetch. Skipped for the alias.packages/opencode/src/provider/provider.ts:1524-1560: the fallback SDK resolver does instantiate@ai-sdk/google-vertexfor the aliased ID via the bundledcreateVertexfactory, butoptions.fetchis absent because the loader was skipped. Requests fail with no credentials attached.- Several downstream call sites compare
model.providerID === "google-vertex"directly (e.g.provider.ts:1431and ~11 sites intransform.ts).
Expected behaviour
Two provider entries that share the same SDK (@ai-sdk/google-vertex) with distinct options should produce two independent SDK instances, each honouring its own project, location, and baseURL. That matches the upstream factory's intended usage: createVertex({ project, location }) returns one provider per call.
Environment
- OpenCode: built from
devbranch (HEAD around77da433e0) - Bun 1.x
@ai-sdk/google-vertex: 4.0.112- Linux
Related
@ai-sdk/google-vertexhas separate upstream URL-construction bugs for theeuandglobalmulti-region values (feat(google-vertex/anthropic): support eu/us multi-region endpoints vercel/ai#14634, @ai-sdk/google-vertex: Broken URL generated when using location: 'global' (Required for gemini-3.1-pro-preview) vercel/ai#14702). Out of scope here; the workaround is to setbaseURLexplicitly. This issue is only about the OpenCode-side gap that stops that workaround from being applied per-instance.- Same code path is the cause of Cannot load custom providers from local file paths #4324 and overlaps with GitHub Copilot integration: Missing custom loader in provider.ts #3019.
Activity
github-actions commentedon May 20, 2026
This issue might be a duplicate of existing issues. Please check:
feat(provider): key provider behaviour off npm where unique
github-actions commentedon Jul 20, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.