{"record":{"id":"afba1efdf7426849","repo":"infiniflow/ragflow","slug":"not-found","errorCode":"NOT_FOUND","errorMessage":"Memory '{memory_id}' not found.","messagePattern":"Memory '(.+?)' not found\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"api/apps/services/memory_api_service.py","lineNumber":67,"sourceCode":"\n\ndef _joined_tenant_ids(user_id: str) -> set[str]:\n    user_tenants = UserTenantService.get_user_tenant_relation_by_user_id(user_id)\n    return {user_id, *[tenant[\"tenant_id\"] for tenant in user_tenants]}\n\n\ndef _memory_accessible(memory) -> bool:\n    if memory.tenant_id == current_user.id:\n        return True\n    if memory.permissions != TenantPermission.TEAM.value:\n        return False\n    return memory.tenant_id in _joined_tenant_ids(current_user.id)\n\n\ndef _require_memory_access(memory_id: str):\n    memory = MemoryService.get_by_memory_id(memory_id)\n    if not memory or not _memory_accessible(memory):\n        raise NotFoundException(f\"Memory '{memory_id}' not found.\")\n    return memory\n\n\ndef _filter_accessible_memories(memory_ids: list[str]):\n    memory_ids = _split_filter_values(memory_ids)\n    if not memory_ids:\n        return []\n    return [memory for memory in MemoryService.get_by_ids(memory_ids) if _memory_accessible(memory)]\n\n\nasync def create_memory(memory_info: dict):\n    \"\"\"\n    :param memory_info: {\n        \"name\": str,\n        \"memory_type\": list[str],\n        \"embd_id\": str,\n        \"llm_id\": str,\n        \"tenant_embd_id\": str | None,","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/apps/services/memory_api_service.py#L49-L85","documentation":"Raised by _require_memory_access when MemoryService.get_by_memory_id returns no row, or when the row exists but the caller is not allowed to see it (not the owner, and either the memory is not TEAM-permission or the caller has not joined that tenant). Deliberately a single NotFound error for both 'missing' and 'forbidden' to avoid leaking existence of other tenants' memories.","triggerScenarios":"GET/PUT/DELETE /api/v1/memory/{memory_id} (or memory-list endpoints filtering by ids) with a wrong/revoked uuid, a memory belonging to another user without TEAM permission, or a team memory from a tenant the caller never joined.","commonSituations":"Stale memory ids kept client-side after deletion; sharing a memory id across accounts without granting team permission; environment resets (DB wiped) while clients hold old ids; copy-paste typos in ids.","solutions":["Re-list memories (GET memory collection) to get fresh, accessible ids and drop cached ones","If the memory belongs to another user, ask the owner to set permissions=TEAM and have the caller join that tenant","Verify the id is the exact uuid returned by the create/list API","Handle 404 as terminal — do not retry; refresh the id source instead"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import uuid\n\ndef valid_memory_id(mid: str) -> bool:\n    try:\n        uuid.UUID(mid)\n        return True\n    except (ValueError, TypeError):\n        return False\n# also: re-list accessible memories and only use returned ids","typeGuard":"def is_memory_id(v) -> bool:\n    return isinstance(v, str) and valid_memory_id(v)","tryCatchPattern":"try:\n    get_memory(mid)\nexcept NotFoundException:\n    memories = list_memories()   # refresh cache of ids\n    if mid not in {m[\"id\"] for m in memories}:\n        drop_cached(mid)         # terminal: forget this id","preventionTips":["Always source memory ids from a fresh list call, never from long-lived caches","Remember 404 also covers 'exists but not shared with you' — request TEAM permission for cross-user access","Do not retry 404s; they are deterministic"],"tags":["memory","authorization","not-found","rest-api"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}