mem0ai/mem0 · error · Error

Failed to parse googleServiceAccountJson: ${err.message}

Error message

Failed to parse googleServiceAccountJson: ${err.message}

What it means

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').

Source

Thrown at mem0-ts/src/oss/src/embeddings/vertexai.ts:89

    this.embeddingTypes = {
      add: config.memoryAddEmbeddingType || "RETRIEVAL_DOCUMENT",
      update: config.memoryUpdateEmbeddingType || "RETRIEVAL_DOCUMENT",
      search: config.memorySearchEmbeddingType || "RETRIEVAL_QUERY",
    };

    const endpoint = `${this.location}-aiplatform.googleapis.com`;
    this.clientOptions = { apiEndpoint: endpoint };

    if (config.vertexCredentialsJson) {
      this.clientOptions.keyFilename = config.vertexCredentialsJson;
    } else if (config.googleServiceAccountJson) {
      try {
        this.clientOptions.credentials =
          typeof config.googleServiceAccountJson === "string"
            ? JSON.parse(config.googleServiceAccountJson)
            : config.googleServiceAccountJson;
      } catch (err) {
        throw new Error(
          "Failed to parse googleServiceAccountJson: " + (err as Error).message,
        );
      }
    }
  }

  private async initClient(): Promise<void> {
    // Memoized so concurrent embed() calls share one client instead of each
    // racing to build (and leak) their own gRPC channel.
    if (!this.initPromise) {
      this.initPromise = this.createClient().catch((err) => {
        this.initPromise = undefined;
        throw err;
      });
    }
    await this.initPromise;
  }

View on GitHub (pinned to 001c235229)

Solutions

  1. Pass the raw contents of the downloaded service-account JSON file: readFileSync('sa.json', 'utf8')
  2. 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
  3. If credentials are base64-encoded in your pipeline, decode before passing
  4. Prefer vertexCredentialsJson with a file path if your runtime mounts the key as a file

Example fix

// before
new VertexAIEmbedder({ googleServiceAccountJson: "/secrets/sa.json" }); // path, not JSON

// after
new VertexAIEmbedder({
  googleServiceAccountJson: require("fs").readFileSync("/secrets/sa.json", "utf8"),
});
Defensive patterns

Strategy: validation

Validate before calling

if (typeof creds === "string") {
  try { JSON.parse(creds); } catch {
    throw new Error("googleServiceAccountJson is not valid JSON - pass file contents, not a path");
  }
}

Type guard

function isServiceAccountJsonParseError(err: unknown): boolean {
  return err instanceof Error && err.message.startsWith("Failed to parse googleServiceAccountJson");
}

Try / catch

try {
  embedder = new VertexAIEmbedder(cfg);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Failed to parse googleServiceAccountJson")) {
    throw new Error("Service account JSON is malformed - re-export the key file verbatim");
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Understand the failure class

Related errors


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/52acb001d068f7da. Report an issue: GitHub.