mem0ai/mem0 · error · Error

organizationId and projectId must be set to update instructi

Error message

organizationId and projectId must be set to update instructions or categories

What it means

updateProject() PATCHes project-level instructions/categories to /api/v1/orgs/organizations/{orgId}/projects/{projectId}/ and enforces the same identity precondition as getProject(): both organizationId and projectId must have been populated by the init ping. Throwing up front prevents an authenticated but misdirected write to a garbage URL.

Source

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

    const params = new URLSearchParams();
    fields?.forEach((field) => params.append("fields", camelToSnake(field)));

    const response = await this._fetchWithErrorHandling(
      `${this.host}/api/v1/orgs/organizations/${this.organizationId}/projects/${this.projectId}/?${params.toString()}`,
      {
        headers: this.headers,
      },
    );
    return response;
  }

  async updateProject(
    prompts: PromptUpdatePayload,
  ): Promise<Record<string, any>> {
    this._captureEvent("update_project", []);
    await this._awaitIdentity();
    if (!(this.organizationId && this.projectId)) {
      throw new Error(
        "organizationId and projectId must be set to update instructions or categories",
      );
    }

    const response = await this._fetchWithErrorHandling(
      `${this.host}/api/v1/orgs/organizations/${this.organizationId}/projects/${this.projectId}/`,
      {
        method: "PATCH",
        headers: this.headers,
        body: JSON.stringify(camelToSnakeKeys(prompts)),
      },
    );
    return response;
  }

  // WebHooks
  async getWebhooks(data?: { projectId?: string }): Promise<Array<Webhook>> {
    this._captureEvent("get_webhooks", []);

View on GitHub (pinned to 001c235229)

Solutions

  1. Use an org/project-scoped platform API key and verify the dashboard shows the org and project.
  2. Ensure any first client call (which triggers/awaits ping) has completed before updateProject().
  3. Confirm the key's project matches the one whose instructions you intend to change.

Example fix

// before
const client = new MemoryClient({ apiKey: process.env.MEM0_API_KEY });
await client.updateProject({ instructions: '...' }); // org/project null

// after
const client = new MemoryClient({ apiKey: process.env.MEM0_PLATFORM_KEY });
await client.users(); // identity resolved
await client.updateProject({ instructions: '...' });
Defensive patterns

Strategy: validation

Validate before calling

// Ensure identity is resolved and scoped before writing project config
await client.users().catch(() => {});
const ping = await fetch(`${host}/v1/ping/`, { headers: { Authorization: `Token ${apiKey}` } }).then(r => r.json());
if (!ping.orgId || !ping.projectId) throw new Error('updateProject requires an org/project-scoped API key');

Type guard

const hasProjectIdentity = (ping: unknown): ping is { orgId: string; projectId: string } =>
  isJsonObject(ping) && typeof ping.orgId === 'string' && typeof ping.projectId === 'string';

Try / catch

try {
  await client.updateProject({ instructions: 'Be terse.' });
} catch (e) {
  if ((e as Error).message.includes('organizationId and projectId must be set')) {
    // write blocked by key scope — fix credentials, do not retry
    throw new Error('updateProject blocked: API key lacks org/project scope');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling updateProject(prompts) with a key that returned no orgId/projectId from ping, or before the async ping has finished. Same shape as the getProject guard but on the write path, so a failure here blocks updating custom instructions.

Common situations: CI scripts updating project prompts with a personal key; racing construction and updateProject; keys rotated to a scope without project access.

Related errors


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