decolua/9router · error · Error
onboardUser done but no project_id in response
Error message
onboardUser done but no project_id in response
What it means
After the onboardUser poll reports done === true, the code extracts the project ID from the response payload. If the payload completes onboarding but contains no recognizable project_id, this error is thrown. It signals an unexpected/changed Google response schema rather than an HTTP failure.
Source
Thrown at open-sse/services/projectId.js:241
signal: localCtrl.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
const errorText = await response.text().catch(() => "");
throw new Error(`onboardUser HTTP ${response.status}: ${errorText.slice(0, 200)}`);
}
const data = await response.json();
if (data.done === true) {
const projectId = extractProjectIdFromOnboard(data);
if (projectId) {
console.log(`[ProjectId] Successfully onboarded, project ID: ${projectId}`);
return projectId;
}
throw new Error("onboardUser done but no project_id in response");
}
// Server not done yet – wait and retry
console.log(`[ProjectId] Onboard attempt ${attempt}/${MAX_ATTEMPTS}: not done yet, waiting...`);
await new Promise(resolve => setTimeout(resolve, 2000));
} catch (error) {
clearTimeout(timeoutId);
if (error.name === "AbortError") {
console.warn(`[ProjectId] onboardUser attempt ${attempt} aborted (timeout or connection removed)`);
if (externalSignal?.aborted) return null; // connection gone – stop retrying
continue;
}
if (attempt === MAX_ATTEMPTS) {
console.warn(`[ProjectId] onboardUser failed after ${MAX_ATTEMPTS} attempts: ${error.message}`);
return null;
}
// Continue to next attempt instead of throwing (which would skip remaining retries)View on GitHub (pinned to 90b52e06ff)
Solutions
- Log the full onboardUser response body to see what fields are actually present
- Re-run loadCodeAssist after onboarding — the project may now be resolvable via the normal path instead of the onboard payload
- Clear the project ID cache (or restart) so a fresh fetch is attempted, then retry
- If Google changed the schema, update extractProjectIdFromOnboard in open-sse/services/projectId.js to match the new field names
Defensive patterns
Strategy: try-catch
Type guard
function hasProjectId(d) {
return Boolean(d && (d.cloudaicompanionProject?.id || d.projectId || d.project_id));
} Try / catch
try {
projectId = await fetchProjectId(accessToken, proxyOptions);
} catch (e) {
if (e.message.includes('no project_id in response')) {
// fall back to loadCodeAssist or a configured default project id
projectId = await loadCodeAssistFallback(accessToken) || cfg.defaultProjectId;
} else throw e;
} Prevention
- Log the raw onboardUser body when this fires so schema drift is visible immediately
- Pin/track the Google Cloud Code API version assumptions and update extractProjectIdFromOnboard when Google changes fields
- Configure a fallback/default project ID for accounts that onboard without a provisioned project
- Clear the project ID cache before re-attempting so a poisoned fetch is not reused
When it happens
Trigger: onboardUser returns HTTP 200 with { done: true } but the response body lacks cloudaicompanionProject/projectId fields — e.g. Google changed the response shape, or the account was onboarded without a provisioned project.
Common situations: Upstream API schema drift after a Google-side change; account onboarded into a state with no auto-created project; a proxy or captive portal returning a manipulated 200 body.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- qoder PAT exchange returned no job token
- No project ID found in response
- Vertex: failed to mint access token from Service Account JSO
- Vertex: failed to refresh access token from ADC JSON (author
- loadCodeAssist failed: HTTP ${response.status} ${errorText.s
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/38265efafbae308f.
Report an issue: GitHub.