unslothai/unsloth · error · HTTPException

Knowledge base not found

Error message

Knowledge base not found

What it means

_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.

Source

Thrown at studio/backend/routes/rag.py:354

    ``conn`` reuses a connection the caller already holds: sqlite-vec loads per
    connection, so opening a second one to read a single row pays that twice.
    """
    if scope_type == "knowledge_base":
        if conn is not None:
            exists = store.get_kb(conn, scope_id) is not None
        else:
            owner_conn = _rag_connection()
            try:
                exists = store.get_kb(owner_conn, scope_id) is not None
            finally:
                owner_conn.close()
        detail = "Knowledge base not found"
    else:
        from storage.studio_db import get_chat_project
        exists = get_chat_project(scope_id) is not None
        detail = "Project not found"
    if not exists:
        raise HTTPException(status_code = 404, detail = detail)


def _require_document_owner(conn: sqlite3.Connection, document: dict) -> None:
    if document.get("kb_id") and store.get_kb(conn, document["kb_id"]) is None:
        raise HTTPException(status_code = 404, detail = "Document not found")
    if document.get("project_id"):
        from storage.studio_db import get_chat_project
        if get_chat_project(document["project_id"]) is None:
            raise HTTPException(status_code = 404, detail = "Document not found")


def _create_linked_folder(scope_type: str, scope_id: str, payload: LinkFolderRequest) -> dict:
    path, signed_identity = _resolve_linked_folder_path(payload.native_path_lease)
    try:
        with folder_sync.scope_lock(_scope_for_owner(scope_type, scope_id)):
            _require_scope_owner(scope_type, scope_id)
            folder, job_id = folder_sync.create_folder_with_sync(
                scope_type = scope_type,

View on GitHub (pinned to 203007d190)

Solutions

  1. Refresh the knowledge-base list and retry against a KB that still exists.
  2. If the ID came from a saved config, re-derive it from the current KB list.
  3. Handle 404 by dropping the stale reference in the client instead of retrying.

Example fix

// before
await api.post(`/rag/knowledge-bases/${staleKbId}/documents`, fd); // 404
// after
const kbs = await api.listKnowledgeBases();
if (!kbs.some(kb => kb.id === staleKbId)) { resetSelection(); return; }
await api.post(`/rag/knowledge-bases/${staleKbId}/documents`, fd);
Defensive patterns

Strategy: type-guard

Validate before calling

const kbs = await api.listKnowledgeBases();
const exists = kbs.some(kb => kb.id === scopeId);
if (!exists) { dropStaleScope(scopeId); return; }

Type guard

const kbExists = (id: string, kbs: Kb[]): id is string =>
  kbs.some(kb => kb.id === id);

Try / catch

if (e.status === 404 && e.detail === 'Knowledge base not found') { reloadKbList(); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/04e7ecebb1602ae9. Report an issue: GitHub.