{"record":{"id":"c870a6a4fb5af227","repo":"mem0ai/mem0","slug":"at-least-one-entity-id-is-required-for-deleteentit-c870a6","errorCode":null,"errorMessage":"At least one entity ID is required for deleteEntities.","messagePattern":"At least one entity ID is required for deleteEntities\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/openclaw/backend/platform.ts","lineNumber":276,"sourceCode":"      return (await this._request(\n        \"DELETE\",\n        `/v1/memories/${memoryId}/`,\n      )) as Record<string, unknown>;\n    }\n    throw new Error(\"Either memoryId or --all is required\");\n  }\n\n  async deleteEntities(opts: EntityIds): Promise<Record<string, unknown>> {\n    // v2 endpoint: DELETE /v2/entities/{entity_type}/{entity_id}/\n    const typeMap: [string, string | undefined][] = [\n      [\"user\", opts.userId],\n      [\"agent\", opts.agentId],\n      [\"app\", opts.appId],\n      [\"run\", opts.runId],\n    ];\n    const entities = typeMap.filter(([, v]) => v) as [string, string][];\n    if (entities.length === 0) {\n      throw new Error(\"At least one entity ID is required for deleteEntities.\");\n    }\n    // Delete each provided entity via the v2 path-based endpoint\n    let result: Record<string, unknown> = {};\n    for (const [entityType, entityId] of entities) {\n      result = (await this._request(\n        \"DELETE\",\n        `/v2/entities/${entityType}/${entityId}/`,\n      )) as Record<string, unknown>;\n    }\n    return result;\n  }\n\n  async ping(): Promise<Record<string, unknown>> {\n    return (await this._request(\"GET\", \"/v1/ping/\")) as Record<string, unknown>;\n  }\n\n  async status(\n    _opts: { userId?: string; agentId?: string } = {},","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/integrations/openclaw/backend/platform.ts#L258-L294","documentation":"Thrown by PlatformBackend.deleteEntities when the EntityIds options object contains none of userId, agentId, appId, or runId. The v2 entity endpoint is path-based (/v2/entities/{entity_type}/{entity_id}/), so at least one entity id is required to build a URL; the guard fires before any HTTP call.","triggerScenarios":"Calling deleteEntities({}) or deleteEntities({ userId: '' }) — empty strings are falsy and filtered out by the typeMap; passing an object with only undefined fields.","commonSituations":"Agent flows that build entity filters dynamically and end up with all-undefined ids; CLI delete-entities command invoked with no entity flags; copy-paste from the entities() listing that forgets to map ids into the call.","solutions":["Supply at least one entity id: deleteEntities({ userId: 'alice' }) — you may pass several and each is deleted sequentially.","Check the ids you are passing are non-empty strings; trim user input before constructing EntityIds.","If you meant to flush everything, that is a different operation: use delete(undefined, { all: true, ... }) instead."],"exampleFix":"// before\nawait backend.deleteEntities({ userId, agentId }); // both undefined\n\n// after\nconst ids = { userId, agentId };\nif (!Object.values(ids).some(Boolean)) {\n  throw new Error('no entity ids resolved — nothing to delete');\n}\nawait backend.deleteEntities(ids);","handlingStrategy":"validation","validationCode":"function hasEntityIds(ids: Partial<Record<'userId'|'agentId'|'appId'|'runId', string>>) {\n  return Object.values(ids).some((v) => typeof v === 'string' && v.trim().length > 0);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build EntityIds from a prior entities() listing so ids are known-good.","Trim and validate user-supplied entity ids before constructing the options object.","Remember delete-all is a separate API (delete with all:true), not deleteEntities({})."],"tags":["validation","entities","platform-mode","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}