mem0ai/mem0 · error · Error

projectId must be set to create a webhook

Error message

projectId must be set to create a webhook

What it means

Thrown by MemoryClient.createWebhook() when the client's internally resolved projectId is null after awaiting identity. Unlike getWebhooks, createWebhook has no per-call projectId override — it relies entirely on the identity resolved from the API key. The webhook registration URL /api/v1/webhooks/projects/{projectId}/ cannot be built without it.

Source

Thrown at mem0-ts/src/client/mem0.ts:692

    if (!data?.projectId) await this._awaitIdentity();
    const project_id = data?.projectId || this.projectId;
    if (!project_id) {
      throw new Error("projectId must be set to access webhooks");
    }
    const response = await this._fetchWithErrorHandling(
      `${this.host}/api/v1/webhooks/projects/${project_id}/`,
      {
        headers: this.headers,
      },
    );
    return response;
  }

  async createWebhook(webhook: WebhookCreatePayload): Promise<Webhook> {
    this._captureEvent("create_webhook", []);
    await this._awaitIdentity();
    if (!this.projectId) {
      throw new Error("projectId must be set to create a webhook");
    }
    const body = {
      name: webhook.name,
      url: webhook.url,
      event_types: webhook.eventTypes,
    };
    const response = await this._fetchWithErrorHandling(
      `${this.host}/api/v1/webhooks/projects/${this.projectId}/`,
      {
        method: "POST",
        headers: this.headers,
        body: JSON.stringify(body),
      },
    );
    return response;
  }

  async updateWebhook(

View on GitHub (pinned to 001c235229)

Solutions

  1. Use an API key that belongs to the target project (Mem0 dashboard -> Project -> API keys), then construct a fresh MemoryClient with it
  2. Confirm projectId resolution with the working sibling call: const hooks = await client.getWebhooks(); — if it also fails, the identity itself lacks a project
  3. Check that the client can reach the identity/ping endpoint (proxy or firewall rules) and that host is correct in ClientOptions

Example fix

// before
const client = new MemoryClient({ apiKey: OLD_PERSONAL_KEY });
await client.createWebhook({ name: 'n', url: 'https://ex.com/h', eventTypes: ['memory.created'] });

// after
const client = new MemoryClient({ apiKey: PROJECT_SCOPED_KEY });
await client.createWebhook({ name: 'n', url: 'https://ex.com/h', eventTypes: ['memory.created'] });
Defensive patterns

Strategy: validation

Validate before calling

// createWebhook has no per-call override; verify identity first via a cheap call
const projects = await client.getOrgsProjects();
if (!projects?.length) {
  throw new Error('API key is not project-scoped; cannot create webhooks');
}
await client.createWebhook({ name, url, eventTypes });

Try / catch

try {
  await client.createWebhook(webhook);
} catch (e) {
  if (e instanceof Error && e.message.includes('projectId must be set')) {
    // configuration error — retrying will not help; surface to operator
    throw new Error('Regenerate the Mem0 API key from inside the target project');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling client.createWebhook({ name, url, eventTypes }) with an API key whose identity carries no project, or when the identity ping could not complete (offline, blocked, or malformed response). Any createWebhook call immediately after client construction where the ping resolved to a null projectId.

Common situations: Personal API key not attached to any project; network egress blocked so the identity ping fails silently before the throw; using a test key against the wrong host (e.g. EU host with a US key).

Related errors


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