{"record":{"id":"ccffff88f9d0da73","repo":"mem0ai/mem0","slug":"projectid-must-be-set-to-access-webhooks","errorCode":null,"errorMessage":"projectId must be set to access webhooks","messagePattern":"projectId must be set to access webhooks","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/client/mem0.ts","lineNumber":677,"sourceCode":"\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\", []);\n    if (!data?.projectId) await this._awaitIdentity();\n    const project_id = data?.projectId || this.projectId;\n    if (!project_id) {\n      throw new Error(\"projectId must be set to access webhooks\");\n    }\n    const response = await this._fetchWithErrorHandling(\n      `${this.host}/api/v1/webhooks/projects/${project_id}/`,\n      {\n        headers: this.headers,\n      },\n    );\n    return response;\n  }\n\n  async createWebhook(webhook: WebhookCreatePayload): Promise<Webhook> {\n    this._captureEvent(\"create_webhook\", []);\n    await this._awaitIdentity();\n    if (!this.projectId) {\n      throw new Error(\"projectId must be set to create a webhook\");\n    }\n    const body = {\n      name: webhook.name,","sourceCodeStart":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/client/mem0.ts#L659-L695","documentation":"Thrown by MemoryClient.getWebhooks() when no project ID is available to build the /api/v1/webhooks/projects/{projectId}/ URL. The hosted client resolves projectId from an async identity ping (_awaitIdentity); if the caller did not pass data.projectId and the resolved identity has no project, the SDK refuses to guess. This is a precondition failure before any HTTP request is made.","triggerScenarios":"Calling client.getWebhooks() with no argument while the API key's identity has no project attached (personal-key-only account, key scoped to an org without a default project, or the identity ping failed/returned null projectId). Also triggered by passing { projectId: \"\" } (empty string is falsy).","commonSituations":"Using a legacy Mem0 API key created before projects existed; running in CI where the identity endpoint is blocked so projectId never populates; migrating from an older SDK that inferred the project differently; account with multiple projects but no default.","solutions":["Pass the project explicitly: await client.getWebhooks({ projectId: 'proj_...' }) — an explicit projectId skips the identity wait entirely","Verify your API key belongs to a project in the Mem0 dashboard (Projects -> select -> API keys) and regenerate the key if the project was created after the key","Confirm the ping endpoint is reachable and returns a payload with projectId (check network tab / client.getOrgsProjects())","If constructing MemoryClient with an orgId/projectId in options, verify those values are correct and non-empty"],"exampleFix":"// before\nconst webhooks = await client.getWebhooks();\n\n// after\nconst webhooks = await client.getWebhooks({ projectId: 'proj_abc123' });","handlingStrategy":"validation","validationCode":"const pid = explicitProjectId ?? (await client.getOrgsProjects())?.[0]?.id;\nif (!pid) throw new Error('No Mem0 project available for this API key');\nconst webhooks = await client.getWebhooks({ projectId: String(pid) });","typeGuard":"const hasProjectId = (d?: { projectId?: string }): d is { projectId: string } =>\n  typeof d?.projectId === 'string' && d.projectId.length > 0;","tryCatchPattern":"try {\n  const webhooks = await client.getWebhooks({ projectId });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('projectId must be set')) {\n    // identity/API-key problem, not transient: fix key scope and fail loudly\n    throw new Error('Mem0 API key has no project scope');\n  }\n  throw e;\n}","preventionTips":["Always pass { projectId } explicitly to getWebhooks instead of relying on identity resolution","Assert at startup that the API key resolves to a project via getOrgsProjects() before serving traffic","Never pass an empty-string projectId — it is falsy and triggers the same throw"],"tags":["webhooks","hosted-api","validation","typescript","project-id"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}