{"record":{"id":"93426c3741134319","repo":"mem0ai/mem0","slug":"organizationid-and-projectid-must-be-set-to-access","errorCode":null,"errorMessage":"organizationId and projectId must be set to access instructions or categories","messagePattern":"organizationId and projectId must be set to access instructions or categories","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/client/mem0.ts","lineNumber":632,"sourceCode":"    const response = await this._fetchWithErrorHandling(\n      `${this.host}/v1/batch/`,\n      {\n        method: \"DELETE\",\n        headers: this.headers,\n        body: JSON.stringify({ memories: memoriesBody }),\n      },\n    );\n    return response;\n  }\n\n  async getProject(options: ProjectOptions): Promise<ProjectResponse> {\n    const payloadKeys = Object.keys(options || {});\n    this._captureEvent(\"get_project\", [payloadKeys]);\n    const { fields } = options;\n    await this._awaitIdentity();\n\n    if (!(this.organizationId && this.projectId)) {\n      throw new Error(\n        \"organizationId and projectId must be set to access instructions or categories\",\n      );\n    }\n\n    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,","sourceCodeStart":614,"sourceCodeEnd":650,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/client/mem0.ts#L614-L650","documentation":"getProject() (which serves project instructions/categories) builds a URL from this.organizationId and this.projectId, which are only populated after the initialization ping returns them for your API key. If either is unset — ping hasn't resolved, or the key has no project context — the client throws instead of issuing a request to a malformed URL like /api/v1/orgs/organizations/null/projects/null/.","triggerScenarios":"Calling getProject() before the async ping completes (this._awaitIdentity() resolved but the key returned no orgId/projectId), using an API key that belongs to no organization/project, or calling from a context where initialization failed silently.","commonSituations":"Personal/free-tier keys with no org; calling getProject immediately after construction before identity resolves; hosted key used where a platform org key is required.","solutions":["Use an API key tied to an organization and project in the Mem0 platform (check the dashboard for your org/project).","Await a trivial client call first (or the client's initialization promise if exposed) so the ping has completed before getProject().","If self-hosting without orgs/projects, don't use getProject — that route exists on the platform API surface only."],"exampleFix":"// before\nconst client = new MemoryClient({ apiKey });\nawait client.getProject({ fields: ['instructions'] }); // org/project still null\n\n// after\nconst client = new MemoryClient({ apiKey: PLATFORM_ORG_KEY });\nawait client.add(messages, { filters: { user_id: 'warmup' } }); // ping completes, identity set\nawait client.getProject({ fields: ['instructions'] });","handlingStrategy":"validation","validationCode":"// Warm up identity before project calls: any first call awaits the ping\nawait client.users().catch(() => {});\n\n// If your key has no org/project, getProject cannot work — verify via a raw ping:\nconst ping = await fetch(`${host}/v1/ping/`, { headers: { Authorization: `Token ${apiKey}` } }).then(r => r.json());\nif (!ping.orgId || !ping.projectId) throw new Error('API key has no org/project context — use a platform 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.getProject({ fields: ['instructions'] });\n} catch (e) {\n  if ((e as Error).message.includes('organizationId and projectId must be set')) {\n    throw new Error('getProject needs an org-scoped API key — check MEM0_API_KEY scope'); // config error, not transient\n  }\n  throw e;\n}","preventionTips":["Use org/project-scoped platform keys whenever you touch instructions or categories.","Trigger and await client initialization before any project-scoped call.","Smoke-test getProject in CI for the exact key you will deploy with."],"tags":["identity","project","configuration","api-key"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}