{"record":{"id":"b6ec98343b07f773","repo":"lfnovo/open-notebook","slug":"error-saving-record-e","errorCode":null,"errorMessage":"Error saving record: {e}","messagePattern":"Error saving record: (.+?)","errorType":"exception","errorClass":"DatabaseOperationError","httpStatus":null,"severity":"critical","filePath":"open_notebook/domain/base.py","lineNumber":195,"sourceCode":"            result_list: List[Dict[str, Any]] = (\n                repo_result if isinstance(repo_result, list) else [repo_result]\n            )\n            for key, value in result_list[0].items():\n                if hasattr(self, key):\n                    if isinstance(getattr(self, key), BaseModel):\n                        setattr(self, key, type(getattr(self, key))(**value))\n                    else:\n                        setattr(self, key, value)\n\n        except ValidationError as e:\n            logger.error(f\"Validation failed: {e}\")\n            raise\n        except RuntimeError:\n            # Transaction conflicts should propagate for retry\n            raise\n        except Exception as e:\n            logger.error(f\"Error saving record: {e}\")\n            raise DatabaseOperationError(e)\n\n    def _prepare_save_data(self) -> Dict[str, Any]:\n        data = self.model_dump()\n        return {\n            key: value\n            for key, value in data.items()\n            if value is not None or key in self.__class__.nullable_fields\n        }\n\n    async def delete(self) -> bool:\n        if self.id is None:\n            raise InvalidInputError(\"Cannot delete object without an ID\")\n        try:\n            logger.debug(f\"Deleting record with id {self.id}\")\n            return await repo_delete(self.id)\n        except Exception as e:\n            logger.error(\n                f\"Error deleting {self.__class__.table_name} with id {self.id}: {str(e)}\"","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/open_notebook/domain/base.py#L177-L213","documentation":"save() re-raises InvalidInputError/RuntimeTime transaction conflicts untouched but wraps every other unexpected exception in DatabaseOperationError after logging 'Error saving record: {e}'. It indicates the write to SurrealDB or record serialization failed at the infrastructure level.","triggerScenarios":"SurrealDB unreachable, unique-constraint/style server rejections, serialization failures on field types, or invalid record data the server refuses. The original exception is attached as the cause for inspection.","commonSituations":"DB container stopped mid-run; model fields holding types SurrealDB can't store (e.g. arbitrary objects); concurrent writes hitting server-side limits; running the worker without the database tier up.","solutions":["Check SurrealDB is up and the API connected at startup (make status)","Inspect logs / e.__cause__ for the server's rejection reason","If type-related, ensure model fields are JSON-serializable (datetime, str, list, dict)","Catch DatabaseOperationError in callers and decide on retry vs user-facing error"],"exampleFix":"# before\nawait note.save()  # unhandled DatabaseOperationError\n\n# after\nfrom open_notebook.domain.errors import DatabaseOperationError\ntry:\n    await note.save()\nexcept DatabaseOperationError as e:\n    logger.error(f\"save failed: {e}\")\n    raise HTTPException(status_code=503, detail=\"Could not save note\")","handlingStrategy":"retry","validationCode":"null","typeGuard":null,"tryCatchPattern":"from open_notebook.domain.errors import DatabaseOperationError\nfor attempt in range(3):\n    try:\n        await note.save()\n        break\n    except DatabaseOperationError:\n        if attempt == 2:\n            raise HTTPException(status_code=503, detail=\"Could not save\")\n        await asyncio.sleep(2 ** attempt)","preventionTips":["Verify SurrealDB is reachable before write-heavy flows","Keep model fields JSON-serializable; test round-trip save+get in CI","Retry transient failures with backoff; only surface to users after retries"],"tags":["database","save","surrealdb","open-notebook"],"backgroundTag":"database-write-failed","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}