{"record":{"id":"2fef8b4e5c0f96dd","repo":"mem0ai/mem0","slug":"organizationid-and-projectid-must-be-set-to-update","errorCode":null,"errorMessage":"organizationId and projectId must be set to update instructions or categories","messagePattern":"organizationId and projectId must be set to update instructions or categories","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/client/mem0.ts","lineNumber":655,"sourceCode":"    const params = new URLSearchParams();\n    fields?.forEach((field) => params.append(\"fields\", camelToSnake(field)));\n\n    const response = await this._fetchWithErrorHandling(\n      `${this.host}/api/v1/orgs/organizations/${this.organizationId}/projects/${this.projectId}/?${params.toString()}`,\n      {\n        headers: this.headers,\n      },\n    );\n    return response;\n  }\n\n  async updateProject(\n    prompts: PromptUpdatePayload,\n  ): Promise<Record<string, any>> {\n    this._captureEvent(\"update_project\", []);\n    await this._awaitIdentity();\n    if (!(this.organizationId && this.projectId)) {\n      throw new Error(\n        \"organizationId and projectId must be set to update instructions or categories\",\n      );\n    }\n\n    const response = await this._fetchWithErrorHandling(\n      `${this.host}/api/v1/orgs/organizations/${this.organizationId}/projects/${this.projectId}/`,\n      {\n        method: \"PATCH\",\n        headers: this.headers,\n        body: JSON.stringify(camelToSnakeKeys(prompts)),\n      },\n    );\n    return response;\n  }\n\n  // WebHooks\n  async getWebhooks(data?: { projectId?: string }): Promise<Array<Webhook>> {\n    this._captureEvent(\"get_webhooks\", []);","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/client/mem0.ts#L637-L673","documentation":"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.","triggerScenarios":"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.","commonSituations":"CI scripts updating project prompts with a personal key; racing construction and updateProject; keys rotated to a scope without project access.","solutions":["Use an org/project-scoped platform API key and verify the dashboard shows the org and project.","Ensure any first client call (which triggers/awaits ping) has completed before updateProject().","Confirm the key's project matches the one whose instructions you intend to change."],"exampleFix":"// before\nconst client = new MemoryClient({ apiKey: process.env.MEM0_API_KEY });\nawait client.updateProject({ instructions: '...' }); // org/project null\n\n// after\nconst client = new MemoryClient({ apiKey: process.env.MEM0_PLATFORM_KEY });\nawait client.users(); // identity resolved\nawait client.updateProject({ instructions: '...' });","handlingStrategy":"validation","validationCode":"// Ensure identity is resolved and scoped before writing project config\nawait client.users().catch(() => {});\nconst ping = await fetch(`${host}/v1/ping/`, { headers: { Authorization: `Token ${apiKey}` } }).then(r => r.json());\nif (!ping.orgId || !ping.projectId) throw new Error('updateProject requires an org/project-scoped API key');","typeGuard":"const hasProjectIdentity = (ping: unknown): ping is { orgId: string; projectId: string } =>\n  isJsonObject(ping) && typeof ping.orgId === 'string' && typeof ping.projectId === 'string';","tryCatchPattern":"try {\n  await client.updateProject({ instructions: 'Be terse.' });\n} catch (e) {\n  if ((e as Error).message.includes('organizationId and projectId must be set')) {\n    // write blocked by key scope — fix credentials, do not retry\n    throw new Error('updateProject blocked: API key lacks org/project scope');\n  }\n  throw e;\n}","preventionTips":["Restrict updateProject calls to deployment scripts that verify key scope first.","Resolve identity (first client call) before any project-scoped write.","Keep a platform org key separate from user-facing keys so scope mistakes are impossible."],"tags":["identity","project","configuration","write-path"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}