lfnovo/open-notebook · warning · HTTPException

Insight not found

Error message

Insight not found

What it means

HTTP 404 from GET /api/insights/{insight_id} when SourceInsight.get returns no insight for the id.

Source

Thrown at api/routers/insights.py:21

from api.models import NoteResponse, SaveAsNoteRequest, SourceInsightResponse
from open_notebook.domain.notebook import SourceInsight
from open_notebook.exceptions import (
    InvalidInputError,
    NotFoundError,
    OpenNotebookError,
)

router = APIRouter()


@router.get("/insights/{insight_id}", response_model=SourceInsightResponse)
async def get_insight(insight_id: str):
    """Get a specific insight by ID."""
    try:
        insight = await SourceInsight.get(insight_id)
        if not insight:
            raise HTTPException(status_code=404, detail="Insight not found")

        # Get source ID from the insight relationship
        source = await insight.get_source()

        return SourceInsightResponse(
            id=insight.id or "",
            source_id=source.id or "",
            insight_type=insight.insight_type,
            content=insight.content,
            created=insight.created.isoformat() if insight.created else None,
            updated=insight.updated.isoformat() if insight.updated else None,
        )
    except HTTPException:
        raise
    except OpenNotebookError:
        raise
    except Exception as e:
        logger.error(f"Error fetching insight {insight_id}: {str(e)}")

View on GitHub (pinned to a7de90d38a)

Solutions

  1. Verify the id is an insight id (not source/note id) from the listing endpoint
  2. If deleted, regenerate or accept the 404 in the client
  3. Confirm you're querying the same database/environment where the insight was created
Defensive patterns

Strategy: validation

Validate before calling

insights = (await client.get("/api/insights")).json()  # or per-source listing
if insight_id not in {i["id"] for i in insights}:
    raise FileNotFoundError(insight_id)

Type guard

def is_insight_id(iid: str, insights: list[dict]) -> bool:
    return iid in {i["id"] for i in insights}

Try / catch

try:
    insight = await client.get(f"/api/insights/{insight_id}")
except httpx.HTTPStatusError as e:
    if e.response.status_code == 404:
        insight = None  # deleted upstream; drop from UI
    else:
        raise

Prevention

When it happens

Trigger: Requesting a deleted/nonexistent insight, using a source id instead of an insight id, or an id from another environment.

Common situations: Insight deleted from the notebook UI while a client still holds its id; copy/paste of the wrong record id type; stale links/exports referencing removed insights.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of lfnovo/open-notebook@a7de90d38a (2026-08-27). Data as JSON: /api/errors/5142b84648135916. Report an issue: GitHub.