{"record":{"id":"52acb001d068f7da","repo":"mem0ai/mem0","slug":"failed-to-parse-googleserviceaccountjson-err-me","errorCode":null,"errorMessage":"Failed to parse googleServiceAccountJson: ${err.message}","messagePattern":"Failed to parse googleServiceAccountJson: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/embeddings/vertexai.ts","lineNumber":89,"sourceCode":"    this.embeddingTypes = {\n      add: config.memoryAddEmbeddingType || \"RETRIEVAL_DOCUMENT\",\n      update: config.memoryUpdateEmbeddingType || \"RETRIEVAL_DOCUMENT\",\n      search: config.memorySearchEmbeddingType || \"RETRIEVAL_QUERY\",\n    };\n\n    const endpoint = `${this.location}-aiplatform.googleapis.com`;\n    this.clientOptions = { apiEndpoint: endpoint };\n\n    if (config.vertexCredentialsJson) {\n      this.clientOptions.keyFilename = config.vertexCredentialsJson;\n    } else if (config.googleServiceAccountJson) {\n      try {\n        this.clientOptions.credentials =\n          typeof config.googleServiceAccountJson === \"string\"\n            ? JSON.parse(config.googleServiceAccountJson)\n            : config.googleServiceAccountJson;\n      } catch (err) {\n        throw new Error(\n          \"Failed to parse googleServiceAccountJson: \" + (err as Error).message,\n        );\n      }\n    }\n  }\n\n  private async initClient(): Promise<void> {\n    // Memoized so concurrent embed() calls share one client instead of each\n    // racing to build (and leak) their own gRPC channel.\n    if (!this.initPromise) {\n      this.initPromise = this.createClient().catch((err) => {\n        this.initPromise = undefined;\n        throw err;\n      });\n    }\n    await this.initPromise;\n  }\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/embeddings/vertexai.ts#L71-L107","documentation":"VertexAIEmbedder accepts a Google service account as a JSON string (or parsed object) via config.googleServiceAccountJson. When a string is supplied, it must be parseable JSON; JSON.parse failure is wrapped in this error with the underlying parse message (e.g. 'Unexpected token ... in JSON at position 0').","triggerScenarios":"Passing the path to a key file instead of its contents; passing the JSON with smart quotes, newlines mangled by shell/env interpolation, or trailing characters; base64-encoded credentials passed without decoding; passing YAML or a PEM key instead of the service-account JSON.","commonSituations":"Storing the service account in an env var that strips or escapes quotes (Docker/Kubernetes secret handling); copy-paste from a terminal that replaced quotes; confusion between vertexCredentialsJson (file path) and googleServiceAccountJson (contents).","solutions":["Pass the raw contents of the downloaded service-account JSON file: readFileSync('sa.json', 'utf8')","If the key lives in an env var, use a file-mounted secret or ensure the variable holds the exact JSON text; validate with JSON.parse before constructing the embedder","If credentials are base64-encoded in your pipeline, decode before passing","Prefer vertexCredentialsJson with a file path if your runtime mounts the key as a file"],"exampleFix":"// before\nnew VertexAIEmbedder({ googleServiceAccountJson: \"/secrets/sa.json\" }); // path, not JSON\n\n// after\nnew VertexAIEmbedder({\n  googleServiceAccountJson: require(\"fs\").readFileSync(\"/secrets/sa.json\", \"utf8\"),\n});","handlingStrategy":"validation","validationCode":"if (typeof creds === \"string\") {\n  try { JSON.parse(creds); } catch {\n    throw new Error(\"googleServiceAccountJson is not valid JSON - pass file contents, not a path\");\n  }\n}","typeGuard":"function isServiceAccountJsonParseError(err: unknown): boolean {\n  return err instanceof Error && err.message.startsWith(\"Failed to parse googleServiceAccountJson\");\n}","tryCatchPattern":"try {\n  embedder = new VertexAIEmbedder(cfg);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Failed to parse googleServiceAccountJson\")) {\n    throw new Error(\"Service account JSON is malformed - re-export the key file verbatim\");\n  }\n  throw err;\n}","preventionTips":["Validate JSON.parse on the secret during config loading, with a clear error","Mount service-account keys as files and pass the path via vertexCredentialsJson","Never hand-edit or shell-escape the JSON; copy it from the downloaded file"],"tags":["vertexai","gcp","credentials","configuration","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}