google-gemini/gemini-cli · error · InvalidNumericProjectIdError

Invalid Google Cloud Project ID

Error message

Invalid Google Cloud Project ID: "${projectId}". The GOOGLE_CLOUD_PROJECT (or GOOGLE_CLOUD_PROJECT_ID) environment variable must be set to your string-based Project ID (e.g., "my-project-123"), not your numeric Project Number. Please update your environment variables.

What it means

Thrown as InvalidNumericProjectIdError by setupUser() when the GOOGLE_CLOUD_PROJECT or GOOGLE_CLOUD_PROJECT_ID environment variable contains a purely numeric string (matches /^\d+$/). Google Cloud project IDs are string-based (e.g., 'my-project-123'); project numbers are numeric and are a different identifier. The Code Assist API requires the string project ID, so a numeric value is always wrong. The error includes the offending value and instructs the user to update their environment.

Solutions

  1. Find your Project ID in the Google Cloud Console (it looks like 'my-project-123', not a pure number) and set export GOOGLE_CLOUD_PROJECT=my-project-123.
  2. Run 'gcloud projects list' to see both the ID and number; copy the ID column.
  3. Update any automation/CI scripts to use the string project ID, not the numeric project number.
  4. Unset the env var to let gcloud's default project config apply: unset GOOGLE_CLOUD_PROJECT.

Example fix

# before — project number (wrong)
export GOOGLE_CLOUD_PROJECT=123456789012

# after — project ID (correct)
export GOOGLE_CLOUD_PROJECT=my-project-123

# Find your project ID
gcloud projects list --format='table(projectId, projectNumber, name)'
Defensive patterns

Strategy: validation

Validate before calling

// Validate project ID format before using it
function isValidProjectId(id: string): boolean {
  // Project IDs are string-based, not purely numeric
  return !/^\d+$/.test(id) && /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/.test(id);
}

const projectId = process.env['GOOGLE_CLOUD_PROJECT'];
if (projectId && !isValidProjectId(projectId)) {
  throw new Error(
    `GOOGLE_CLOUD_PROJECT='${projectId}' looks like a Project Number. Use the string Project ID instead.`
  );
}

Type guard

function isStringProjectId(id: string | undefined): id is string {
  return typeof id === 'string' && id.length > 0 && !/^\d+$/.test(id);
}

Try / catch

try {
  await setupUser(client, config, httpOptions);
} catch (e) {
  if (e instanceof InvalidNumericProjectIdError) {
    console.error(
      `GOOGLE_CLOUD_PROJECT is set to a numeric Project Number. ` +
      `Find your Project ID with 'gcloud projects list' and set it instead.`
    );
    process.exit(2);
  }
  throw e;
}

Prevention

When it happens

Trigger: setupUser() reads GOOGLE_CLOUD_PROJECT (or GOOGLE_CLOUD_PROJECT_ID) from process.env, finds it matches /^\d+$/, and throws InvalidNumericProjectIdError. For example, setting export GOOGLE_CLOUD_PROJECT=123456789012 (a project number) triggers this.

Common situations: User copied the Project Number from the Google Cloud Console instead of the Project ID; automation scripts that inject the numeric project identifier; confusion between 'Project ID' (string) and 'Project Number' (integer) in GCP console; terraform/infrastructure scripts outputting the number instead of the ID.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/7f19fcad3e463c9b. Report an issue: GitHub.

Appendix: source

Thrown at packages/core/src/code_assist/setup.ts:135

 * @param httpOptions - Optional HTTP options
 * @returns The user's project ID, tier ID, and tier name
 * @throws {ValidationRequiredError} If account validation is required
 * @throws {ProjectIdRequiredError} If no project ID is available and required
 * @throws {ValidationCancelledError} If user cancels validation
 * @throws {ChangeAuthRequestedError} If user requests to change auth method
 */
export async function setupUser(
  client: AuthClient,
  config: Config,
  httpOptions: HttpOptions = {},
): Promise<UserData> {
  const projectId =
    process.env['GOOGLE_CLOUD_PROJECT'] ||
    process.env['GOOGLE_CLOUD_PROJECT_ID'] ||
    undefined;

  if (projectId && /^\d+$/.test(projectId)) {
    throw new InvalidNumericProjectIdError(projectId);
  }

  const projectCache = userDataCache.getOrCreate(client, () =>
    createCache<string | undefined, Promise<UserData>>({
      storage: 'map',
      defaultTtl: 30000, // 30 seconds
    }),
  );

  return projectCache.getOrCreate(projectId, () =>
    _doSetupUser(client, projectId, config, httpOptions),
  );
}

/**
 * Internal implementation of the user setup logic.
 */
async function _doSetupUser(

View on GitHub (pinned to 5024443c72)