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

  1. Log the full onboardUser response body to see what fields are actually present
  2. Re-run loadCodeAssist after onboarding — the project may now be resolvable via the normal path instead of the onboard payload
  3. Clear the project ID cache (or restart) so a fresh fetch is attempted, then retry
  4. 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

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


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/38265efafbae308f. Report an issue: GitHub.