{"record":{"id":"7f5060f42af214fa","repo":"continuedev/continue","slug":"vertexai-keyjson-must-contain-a-valid-private-key-7f5060","errorCode":null,"errorMessage":"VertexAI: keyJson must contain a valid private key","messagePattern":"VertexAI: keyJson must contain a valid private key","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/openai-adapters/src/apis/VertexAI.ts","lineNumber":103,"sourceCode":"      // Standard mode validation\n      if (!region || !projectId) {\n        throw new Error(\n          \"region and projectId are required for VertexAI (when not using express/apiKey mode)\",\n        );\n      }\n      if (keyFile && keyJson) {\n        throw new Error(\n          \"VertexAI credentials can be configured with either keyFile or keyJson but not both\",\n        );\n      }\n    }\n\n    // Set up authentication client\n    if (keyJson) {\n      try {\n        const parsed = JSON.parse(keyJson);\n        if (!parsed?.private_key) {\n          throw new Error(\"VertexAI: keyJson must contain a valid private key\");\n        }\n        parsed.private_key = parsed.private_key.replace(/\\\\n/g, \"\\n\");\n        const jsonClient = auth.fromJSON(parsed);\n        if (jsonClient instanceof JWT) {\n          jsonClient.scopes = [VertexAIApi.AUTH_SCOPES];\n        } else {\n          throw new Error(\"VertexAI: keyJson must be a valid JWT\");\n        }\n        this.clientPromise = Promise.resolve(jsonClient);\n      } catch (e) {\n        throw new Error(\"VertexAI: Failed to parse keyJson\");\n      }\n    } else if (keyFile) {\n      if (typeof keyFile !== \"string\") {\n        throw new Error(\"VertexAI: keyFile must be a string\");\n      }\n      this.clientPromise = new GoogleAuth({\n        scopes: VertexAIApi.AUTH_SCOPES,","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/continuedev/continue/blob/5522c6f44ca0ac3528b37244818fbfa39b5af470/packages/openai-adapters/src/apis/VertexAI.ts#L85-L121","documentation":"When authenticating with keyJson, the adapter parses the JSON and requires a private_key field. If parsing succeeds but private_key is absent, this error is thrown; malformed JSON would instead throw from JSON.parse.","triggerScenarios":"Passing a keyJson string that is valid JSON but lacks private_key — e.g. a cropped service-account file, a JWT payload, or a Firebase web config.","commonSituations":"Copying the wrong JSON from Google Cloud console; env var truncation breaking the file; passing a key-file with escaped quotes mangled; using a bare OAuth client config instead of a service-account key.","solutions":["Regenerate and download a full service-account JSON key from GCP IAM and use its exact contents","Verify the JSON includes private_key, client_email, and project_id before passing it","Ensure \\\\n sequences inside private_key are preserved (the adapter normalizes them itself)"],"exampleFix":"// before\nkeyJson: JSON.stringify({ type: 'service_account', project_id: 'p' }) // no private_key\n// after\nkeyJson: fs.readFileSync('svc-account.json', 'utf8') // full service-account key file","handlingStrategy":"validation","validationCode":"const parsed = JSON.parse(keyJson); if (!parsed.private_key) throw new Error('keyJson is not a service-account key');","typeGuard":"const isServiceAccountKey = (s: string): boolean => { try { return 'private_key' in JSON.parse(s); } catch { return false; } };","tryCatchPattern":"try { new VertexAIApi(cfg); } catch (e) { if (e.message.includes('valid private key')) throw new ConfigError('keyJson must be a full service-account JSON key'); throw e; }","preventionTips":["Download fresh service-account keys from GCP IAM","Validate keyJson contains private_key before constructing","Avoid manual copy-paste of key JSON; read from file"],"tags":["vertexai","authentication","service-account","key-json"],"backgroundTag":"invalid-credentials","analyzedSha":"5522c6f44ca0ac3528b37244818fbfa39b5af470","analyzedAt":"2026-08-27T11:28:54.683Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}