HKUDS/DeepTutor · error · HTTPException

str(e)

Error message

str(e)

What it means

Generic translation of a domain ValueError raised while connecting an Obsidian vault (POST /connect-obsidian): the try block calls assert_path_allowed(vault_path) and manager.register_obsidian_vault(...), either of which raises ValueError for a path outside the allowed roots, a missing/invalid vault directory, or a conflicting KB name. The HTTP 400 detail is just str(e), i.e. whatever the underlying validation helper reported.

Solutions

  1. Read the returned detail to identify the underlying cause (path not allowed, directory missing, invalid name)
  2. Use a vault_path that passes the server path-allowlist and exists on the host
  3. Choose a KB name that does not conflict with an existing one
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at deeptutor/api/routers/knowledge.py:1735 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

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

    local/self-hosted deployment); the Obsidian capability reads it live.
    """
    name = (payload.name or "").strip()
    vault_path = (payload.vault_path or "").strip()
    if not name or not vault_path:
        raise HTTPException(status_code=400, detail="Both name and vault_path are required.")
    try:
        folder = assert_path_allowed(vault_path)
        manager = get_kb_manager()
        entry = manager.register_obsidian_vault(name, str(folder))
        return {"status": "connected", "name": name, "vault_path": entry["vault_path"]}
    except ValueError as e:
        # Missing/invalid path, disallowed location, or a name clash → 400.
        raise HTTPException(status_code=400, detail=str(e))
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error connecting Obsidian vault: {e}")
        raise HTTPException(status_code=500, detail=str(e))


class ConnectMarginNote4Request(BaseModel):
    name: str
    db_path: str = ""
    description: str = ""


@router.post("/connect-marginnote4")
async def connect_marginnote4(payload: ConnectMarginNote4Request):
    """Register a connected MarginNote 4 library as a knowledge base.

    Creates a ``type: marginnote4`` pointer so the MarginNote capability can
    bind to it on turns where the user selects this KB. When ``db_path`` is
    omitted the capability derives a default SQLite path from the KB name.
    """
    name = (payload.name or "").strip()
    if not name:

View on GitHub (pinned to 3e82f13042)