{"record":{"id":"3abedd58181293d8","repo":"lfnovo/open-notebook","slug":"error-updating-transformation-str-e","errorCode":null,"errorMessage":"Error updating transformation: {str(e)}","messagePattern":"Error updating transformation: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"api/routers/transformations.py","lineNumber":249,"sourceCode":"            # Validate a newly supplied model reference (allow clearing to None).\n            if transformation_update.model_id:\n                model = await Model.get(transformation_update.model_id)\n                if not model:\n                    raise HTTPException(status_code=404, detail=\"Model not found\")\n            transformation.model_id = transformation_update.model_id\n\n        await transformation.save()\n\n        return _transformation_response(transformation)\n    except HTTPException:\n        raise\n    except InvalidInputError as e:\n        raise HTTPException(status_code=400, detail=str(e))\n    except OpenNotebookError:\n        raise\n    except Exception as e:\n        logger.error(f\"Error updating transformation {transformation_id}: {str(e)}\")\n        raise HTTPException(\n            status_code=500, detail=f\"Error updating transformation: {str(e)}\"\n        )\n\n\n@router.delete(\"/transformations/{transformation_id}\")\nasync def delete_transformation(transformation_id: str):\n    \"\"\"Delete a transformation.\"\"\"\n    try:\n        transformation = await Transformation.get(transformation_id)\n        if not transformation:\n            raise HTTPException(status_code=404, detail=\"Transformation not found\")\n\n        await transformation.delete()\n\n        return {\"message\": \"Transformation deleted successfully\"}\n    except HTTPException:\n        raise\n    except OpenNotebookError:","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/api/routers/transformations.py#L231-L267","documentation":"Generic 500 from PUT /transformations/{transformation_id} when saving or serializing the updated record fails with an unexpected exception. Distinct from the 400 (validation) and 404 (missing record/model) paths; this indicates persistence or internal errors.","triggerScenarios":"PUT with valid fields while SurrealDB is unavailable, the save conflicts with a concurrent writer, or the response serialization hits an unexpected attribute.","commonSituations":"Database outage mid-request, concurrent edits to the same transformation, or stale DB schema after upgrading Open Notebook without letting migrations run.","solutions":["Check API logs for the exact exception message logged before the 500","Confirm SurrealDB is running and responsive","Re-fetch the transformation and re-apply your changes to avoid stale-state conflicts","Restart the API so automatic schema migrations execute"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"assert (await client.get(f'/transformations/{tid}')).status_code == 200, 'record missing or DB unhealthy'","typeGuard":null,"tryCatchPattern":"resp = await client.put(f'/transformations/{tid}', json=patch)\nif resp.status_code >= 500:\n    await asyncio.sleep(2)\n    resp = await client.put(f'/transformations/{tid}', json=patch)\nresp.raise_for_status()","preventionTips":["Avoid concurrent edits to the same transformation","Keep SurrealDB running through the whole update request","Check server logs for the underlying exception on 500"],"tags":["fastapi","http-500","transformation","surrealdb","update"],"backgroundTag":"database-write-failed","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}