decolua/9router · error
Vertex: could not resolve project_id from API key. Please…
Error message
Vertex: could not resolve project_id from API key. Please add it manually in provider settings.
What it means
Thrown in VertexExecutor.execute (open-sse/executors/vertex.js:157) when a 'vertex-partner' connection uses a raw API key (no SA JSON, no ADC, no providerSpecificData.projectId) and the automatic project-ID resolution fails. resolveProjectId sends a probe request to the Vertex publisher endpoint with the key and parses projects/{id} out of Google's error message; if that extraction finds nothing, execution stops here.
Solutions
- Manually set projectId in the Vertex partner provider's settings (providerSpecificData.projectId) — this is exactly what the error message asks for and skips auto-resolution entirely.
- Verify the API key is valid (try a curl to the Vertex endpoint with ?key=...) — invalid keys won't yield a parseable project path.
- Check network/proxy access to https://aiplatform.googleapis.com; the probe must get a JSON error body containing projects/{id}.
- Alternatively switch to a Service Account JSON credential, which carries project_id natively.
Example fix
// before
{ "apiKey": "AQ.Ab8R..." }
// after
{ "apiKey": "AQ.Ab8R...", "providerSpecificData": { "projectId": "my-gcp-project" } } Defensive patterns
Strategy: validation
Validate before calling
if (provider === "vertex-partner" && !parseVertexSaJson(creds?.apiKey) && !parseVertexAdcJson(creds?.apiKey) && !creds?.providerSpecificData?.projectId) {
console.warn("vertex-partner: no projectId — auto-resolution may fail; set providerSpecificData.projectId");
} Type guard
function canResolveVertexPartnerProject(creds) {
return Boolean(parseVertexSaJson(creds?.apiKey) || parseVertexAdcJson(creds?.apiKey) || (typeof creds?.providerSpecificData?.projectId === "string" && creds.providerSpecificData.projectId.trim()));
} Try / catch
try {
await chat(model, body);
} catch (e) {
if (/could not resolve project_id from API key/.test(e.message)) {
showProjectIdSettingsPrompt();
} else throw e;
} Prevention
- Set projectId explicitly in provider settings instead of relying on the probe.
- Verify the raw API key works before saving it (a dead key defeats auto-resolution).
- Ensure outbound access to aiplatform.googleapis.com so the probe can return a parseable error.
- Remember projectId resolution results are cached per key — fix the key, not just the setting, if you rely on auto-resolution.
When it happens
Trigger: provider is 'vertex-partner', apiKey is a raw key, providerSpecificData.projectId is unset, and the resolveProjectId probe either fails to reach aiplatform.googleapis.com, returns a non-JSON body, or returns an error message that does not contain 'projects/{id}/' (e.g. an auth-quota error shape that omits the project path).
Common situations: Express-mode Vertex API key that is invalid/expired, so Google returns a bare credential error without the project path; network egress to aiplatform.googleapis.com blocked; a proxy returns an HTML error page; key valid but the probe response shape changed.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- API key required
- Vertex OAuth/ADC requires a project_id. Add…
- Vertex partner models require a project_id. Add it in…
- API key is required
- API key returned no available models
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/96cd994385a76c3c.
Report an issue: GitHub.
Appendix: source
Thrown at open-sse/executors/vertex.js:157
credentials.accessToken = result.accessToken;
}
// ADC user credential flow: refresh Bearer token via Google OAuth2 token endpoint
if (adcJson) {
const result = await refreshGoogleToken(
adcJson.refresh_token,
adcJson.client_id,
adcJson.client_secret,
log
);
if (!result?.accessToken) throw new Error("Vertex: failed to refresh access token from ADC JSON (authorized_user)");
credentials.accessToken = result.accessToken;
}
// vertex-partner with raw key: auto-resolve project_id if not provided
if (this.provider === "vertex-partner" && !saJson && !adcJson && !credentials?.providerSpecificData?.projectId) {
const projectId = await resolveProjectId(credentials.apiKey);
if (!projectId) throw new Error("Vertex: could not resolve project_id from API key. Please add it manually in provider settings.");
log?.debug?.("VERTEX", `Resolved project_id: ${projectId}`);
credentials.providerSpecificData = { ...credentials.providerSpecificData, projectId };
}
const url = this.buildUrl(model, stream, 0, credentials);
const headers = this.buildHeaders(credentials, stream);
const transformedBody = this.transformRequest(model, body, stream, credentials);
const response = await proxyAwareFetch(url, {
method: "POST",
headers,
body: JSON.stringify(transformedBody),
signal,
}, proxyOptions);
return { response, url, headers, transformedBody };
}
}View on GitHub (pinned to 90b52e06ff)