HKUDS/DeepTutor · error · HTTPException

Knowledge base '{kb_name}' is connected to an external resou

Error message

Knowledge base '{kb_name}' is connected to an external resource and is read-only. Local file operations and re-indexing are not available for it.

What it means

Raised by _assert_not_connected_kb when is_connected_kb(kb_entry) is true — the KB is a read-only pointer to an external resource (e.g. an Obsidian vault or linked external index). Writes and re-indexing are deliberately forbidden; HTTP 409.

Source

Thrown at deeptutor/api/routers/knowledge.py:789

    raise HTTPException(status_code=404, detail=f"Knowledge base '{requested}' not found")


def _load_kb_entry_or_404(manager: KnowledgeBaseManager, kb_name: str) -> dict:
    manager.config = manager._load_config()
    kb_entry = manager.config.get("knowledge_bases", {}).get(kb_name)
    if kb_entry is None:
        raise HTTPException(status_code=404, detail=f"Knowledge base '{kb_name}' not found")
    return kb_entry


def _assert_not_connected_kb(kb_name: str, kb_entry: dict) -> None:
    """Block writes to connected KBs (Obsidian vaults, linked indexes).

    They are read-only pointers to the user's external files — we never write
    into or re-index them.
    """
    if is_connected_kb(kb_entry):
        raise HTTPException(
            status_code=409,
            detail=(
                f"Knowledge base '{kb_name}' is connected to an external resource and is "
                "read-only. Local file operations and re-indexing are not available for it."
            ),
        )


def _assert_kb_writable_or_409(kb_name: str, kb_entry: dict) -> None:
    _assert_not_connected_kb(kb_name, kb_entry)
    if bool(kb_entry.get("needs_reindex", False)):
        raise HTTPException(
            status_code=409,
            detail=(
                f"Knowledge base '{kb_name}' uses legacy index format and needs reindex "
                "before accepting incremental uploads."
            ),
        )

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Write to a local (non-connected) KB instead
  2. If ingestion is needed, copy the external files into a local KB
  3. Re-index the source externally (for vaults, let the external tool manage it)

Example fix

# before
upload_files(kb='my-obsidian-vault', ...)
# after
upload_files(kb='local-kb', ...)
Defensive patterns

Strategy: type-guard

Validate before calling

from deeptutor.api.routers.knowledge import is_connected_kb
if is_connected_kb(kb_entry): block_write_ui(kb_name)

Type guard

def is_writable_kb(kb_entry: dict) -> bool:
    return not is_connected_kb(kb_entry) and not kb_entry.get('needs_reindex', False)

Prevention

When it happens

Trigger: Attempting folder creation, file move/delete, upload, or reindex on a connected/linked KB instead of a local one.

Common situations: User links an Obsidian vault then tries to upload into it from the Files UI; automation scripts iterating all KBs and applying write operations indiscriminately.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/3508228f2f057b0f. Report an issue: GitHub.