decolua/9router · error · Error

Failed to fetch project ID: ${error}

Error message

Failed to fetch project ID: ${error}

What it means

GeminiCLIService.fetchProjectId() (src/lib/oauth/services/gemini.js:85) calls Google's Cloud Code Assist endpoint (cloudcode-pa.googleapis.com/v1internal:loadCodeAssist) with the fresh access token to discover the user's cloudaicompanionProject. A non-2xx response is wrapped into 'Failed to fetch project ID: <body>' and thrown, mid-way through connect() after tokens were already obtained.

Source

Thrown at src/lib/oauth/services/gemini.js:85

      {
        method: "POST",
        headers: {
          "Authorization": `Bearer ${accessToken}`,
          "Content-Type": "application/json",
          "User-Agent": "google-api-nodejs-client/9.15.1",
          "X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1",
          "Client-Metadata": JSON.stringify(getOAuthClientMetadata())
        },
        body: JSON.stringify({
          metadata: getOAuthClientMetadata(),
          mode: 1
        })
      }
    );

    if (!response.ok) {
      const error = await response.text();
      throw new Error(`Failed to fetch project ID: ${error}`);
    }

    const data = await response.json();

    // Extract project ID
    let projectId = "";
    if (typeof data.cloudaicompanionProject === "string") {
      projectId = data.cloudaicompanionProject.trim();
    } else if (data.cloudaicompanionProject?.id) {
      projectId = data.cloudaicompanionProject.id.trim();
    }

    if (!projectId) {
      throw new Error("No project ID found in response");
    }

    return projectId;
  }

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Read the embedded body for the status code and Google error details (401/403 vs 429 vs 5xx).
  2. For 401/403: re-run connect(), approve ALL requested scopes on the consent screen, and verify the account has Gemini Code Assist available.
  3. For 429: wait and retry — the call is rate-limited per account.
  4. For 5xx: retry after a short backoff; if it persists, check whether Google changed the loadCodeAssist endpoint and update the URL/metadata in fetchProjectId.
  5. Confirm system clock correctness — a skewed clock invalidates bearer tokens right after exchange.

Example fix

// before
if (!response.ok) {
  const error = await response.text();
  throw new Error(`Failed to fetch project ID: ${error}`);
}
// after
if (!response.ok) {
  const error = await response.text();
  if (response.status >= 500 || response.status === 429) {
    await new Promise((r) => setTimeout(r, 2000));
    return this.fetchProjectId(accessToken); // transient — retry once
  }
  throw new Error(`Failed to fetch project ID (HTTP ${response.status}): ${error}`);
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-checks before the loadCodeAssist call
if (!accessToken) throw new Error("Access token required for loadCodeAssist");
// optionally verify token works first via getUserInfo(), which fails faster on 401

Type guard

function isTransientHttpError(status) {
  return status === 429 || status >= 500;
}

Try / catch

try {
  const projectId = await geminiService.fetchProjectId(tokens.access_token);
} catch (err) {
  const m = /Failed to fetch project ID: (.*)/s.exec(err.message);
  if (m && /401|403/.test(m[1])) {
    console.error("Account lacks Code Assist access or scopes were not granted — re-run connect() and approve all scopes.");
  } else if (m && /429|5\d\d/.test(m[1])) {
    console.error("Transient Google error — retry after backoff.");
  } else throw err;
}

Prevention

When it happens

Trigger: Calling fetchProjectId(accessToken) when Google replies non-2xx — 401/403 when the token lacks the cloud-platform scope or the account has no Code Assist entitlement, 404 when the internal API shape/URL changed, 429 on quota, or 5xx from Google.

Common situations: The Google account is a Workspace account without Cloud Code Assist enabled; the user denied the requested scopes on the consent screen; Google changed the v1internal API contract (common for internal endpoints); transient Google-side outage right after login.

Related errors


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