{"record":{"id":"04e7ecebb1602ae9","repo":"unslothai/unsloth","slug":"knowledge-base-not-found","errorCode":null,"errorMessage":"Knowledge base not found","messagePattern":"Knowledge base not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"studio/backend/routes/rag.py","lineNumber":354,"sourceCode":"    ``conn`` reuses a connection the caller already holds: sqlite-vec loads per\n    connection, so opening a second one to read a single row pays that twice.\n    \"\"\"\n    if scope_type == \"knowledge_base\":\n        if conn is not None:\n            exists = store.get_kb(conn, scope_id) is not None\n        else:\n            owner_conn = _rag_connection()\n            try:\n                exists = store.get_kb(owner_conn, scope_id) is not None\n            finally:\n                owner_conn.close()\n        detail = \"Knowledge base not found\"\n    else:\n        from storage.studio_db import get_chat_project\n        exists = get_chat_project(scope_id) is not None\n        detail = \"Project not found\"\n    if not exists:\n        raise HTTPException(status_code = 404, detail = detail)\n\n\ndef _require_document_owner(conn: sqlite3.Connection, document: dict) -> None:\n    if document.get(\"kb_id\") and store.get_kb(conn, document[\"kb_id\"]) is None:\n        raise HTTPException(status_code = 404, detail = \"Document not found\")\n    if document.get(\"project_id\"):\n        from storage.studio_db import get_chat_project\n        if get_chat_project(document[\"project_id\"]) is None:\n            raise HTTPException(status_code = 404, detail = \"Document not found\")\n\n\ndef _create_linked_folder(scope_type: str, scope_id: str, payload: LinkFolderRequest) -> dict:\n    path, signed_identity = _resolve_linked_folder_path(payload.native_path_lease)\n    try:\n        with folder_sync.scope_lock(_scope_for_owner(scope_type, scope_id)):\n            _require_scope_owner(scope_type, scope_id)\n            folder, job_id = folder_sync.create_folder_with_sync(\n                scope_type = scope_type,","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/rag.py#L336-L372","documentation":"_require_scope_owner() checks that the scope being addressed exists: for knowledge-base scope, store.get_kb(conn, scope_id) on a RAG connection; the 404 detail is 'Knowledge base not found' (the sibling branch for projects yields 'Project not found'). Raised before any mutation so requests against deleted or never-created KBs fail fast.","triggerScenarios":"Any RAG request scoped to a kb_id that does not exist in the knowledge_bases table — listing/uploading/deleting documents, linking folders — e.g. after the KB was deleted in another tab or by another user, or with a mistyped/fabricated kb_id.","commonSituations":"Stale UI after the KB was removed elsewhere; client holds an old ID across sessions; race where a delete finishes between page load and the next API call; copy-paste of an ID with whitespace or truncation.","solutions":["Refresh the knowledge-base list and retry against a KB that still exists.","If the ID came from a saved config, re-derive it from the current KB list.","Handle 404 by dropping the stale reference in the client instead of retrying."],"exampleFix":"// before\nawait api.post(`/rag/knowledge-bases/${staleKbId}/documents`, fd); // 404\n// after\nconst kbs = await api.listKnowledgeBases();\nif (!kbs.some(kb => kb.id === staleKbId)) { resetSelection(); return; }\nawait api.post(`/rag/knowledge-bases/${staleKbId}/documents`, fd);","handlingStrategy":"type-guard","validationCode":"const kbs = await api.listKnowledgeBases();\nconst exists = kbs.some(kb => kb.id === scopeId);\nif (!exists) { dropStaleScope(scopeId); return; }","typeGuard":"const kbExists = (id: string, kbs: Kb[]): id is string =>\n  kbs.some(kb => kb.id === id);","tryCatchPattern":"if (e.status === 404 && e.detail === 'Knowledge base not found') { reloadKbList(); }","preventionTips":["Re-resolve kb_id from the live list before each scoped operation.","Invalidate cached scope IDs whenever the KB list changes.","Treat 404 as permanent for that ID — never auto-retry."],"tags":["http-404","knowledge-base","scope-validation","rag","studio-backend"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}