lfnovo/open-notebook · error · HTTPException

Error fetching transformation

Error message

Error fetching transformation: {str(e)}

What it means

Generic 500 from GET /transformations/{transformation_id} when fetching the record raises an unexpected exception (i.e. not the clean not-found case). Typically a SurrealDB query error or record deserialization problem inside Transformation.get.

Solutions

  1. Check API logs for the underlying exception message
  2. Confirm the ID format matches existing transformation IDs (compare with GET /transformations output)
  3. Verify SurrealDB is reachable and restart the API if the connection pool went stale
Defensive patterns

Strategy: try-catch

Validate before calling

def looks_like_record_id(rid: str) -> bool:
    return bool(rid) and ':' in rid

Try / catch

resp = await client.get(f'/transformations/{tid}')
if resp.status_code == 500:
    logger.error('fetch failed', resp.json().get('detail'))
    # verify DB health before retrying
if resp.status_code == 404:
    ...  # genuine not-found

Prevention

When it happens

Trigger: GET /api/transformations/{id} with a malformed record ID that crashes the SurrealDB query parser, or while the database connection has dropped.

Common situations: Passing a raw ID without the record prefix, a SurrealDB restart mid-session, or version drift between the model class and stored records.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at api/routers/transformations.py:202

@router.get(
    "/transformations/{transformation_id}", response_model=TransformationResponse
)
async def get_transformation(transformation_id: str):
    """Get a specific transformation by ID."""
    try:
        transformation = await Transformation.get(transformation_id)
        if not transformation:
            raise HTTPException(status_code=404, detail="Transformation not found")

        return _transformation_response(transformation)
    except HTTPException:
        raise
    except OpenNotebookError:
        raise
    except Exception as e:
        logger.error(f"Error fetching transformation {transformation_id}: {str(e)}")
        raise HTTPException(
            status_code=500, detail=f"Error fetching transformation: {str(e)}"
        )


@router.put(
    "/transformations/{transformation_id}", response_model=TransformationResponse
)
async def update_transformation(
    transformation_id: str, transformation_update: TransformationUpdate
):
    """Update a transformation."""
    try:
        transformation = await Transformation.get(transformation_id)
        if not transformation:
            raise HTTPException(status_code=404, detail="Transformation not found")

        # Update only provided fields
        if transformation_update.name is not None:

View on GitHub (pinned to a7de90d38a)