{"record":{"id":"aa8e998d8283d00e","repo":"lfnovo/open-notebook","slug":"failed-to-update-record-str-e","errorCode":null,"errorMessage":"Failed to update record: {str(e)}","messagePattern":"Failed to update record: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"open_notebook/database/repository.py","lineNumber":205,"sourceCode":"        _ensure_safe_identifier(table, \"table\")\n        if isinstance(id, RecordID):\n            record_id: RecordID = id\n        elif \":\" in id and id.startswith(f\"{table}:\"):\n            record_id = ensure_record_id(id)\n        else:\n            record_id = RecordID(table, id)\n        data.pop(\"id\", None)\n        if \"created\" in data and isinstance(data[\"created\"], str):\n            data[\"created\"] = datetime.fromisoformat(data[\"created\"])\n        data[\"updated\"] = datetime.now(timezone.utc)\n        query = \"UPDATE $target MERGE $data;\"\n        # logger.debug(f\"Update query: {query}\")\n        result = await repo_query(query, {\"target\": record_id, \"data\": data})\n        # if isinstance(result, list):\n        #     return [_return_data(item) for item in result]\n        return parse_record_ids(result)\n    except Exception as e:\n        raise RuntimeError(f\"Failed to update record: {str(e)}\")\n\n\nasync def repo_delete(record_id: Union[str, RecordID]):\n    \"\"\"Delete a record by record id\"\"\"\n\n    try:\n        async with db_connection() as connection:\n            return await connection.delete(ensure_record_id(record_id))\n    except Exception as e:\n        logger.exception(e)\n        raise RuntimeError(f\"Failed to delete record: {str(e)}\")\n\n\nasync def repo_insert(\n    table: str, data: List[Dict[str, Any]], ignore_duplicates: bool = False\n) -> List[Dict[str, Any]]:\n    \"\"\"Create a new record in the specified table\"\"\"\n    try:","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/lfnovo/open-notebook/blob/a7de90d38aaf18ee85fd661854d35c11e44613e2/open_notebook/database/repository.py#L187-L223","documentation":"repo_update() executes a SurrealQL UPDATE and wraps any exception as RuntimeError('Failed to update record: <cause>'). Unlike repo_create it embeds the cause in the message, so the text names the actual problem — commonly 'record not found', schema type mismatches, or fields not defined in the schema when the table is schemafull.","triggerScenarios":"Updating a record id that no longer exists; sending None where the schema requires a type; updating a field not present in a SCHEMAFULL table definition; serializing unsupported Python objects (datetime, enums) into the data dict.","commonSituations":"Concurrent deletes racing an update; stale record ids held in frontend state after another client deleted the row; model changes adding fields without a migration; passing raw datetime/Enum objects in the data payload.","solutions":["Read the appended cause text — it is the actual SurrealDB error","If 'not found', verify the record still exists (repo_query by id) and refresh stale ids in the caller","Ensure new model fields have a corresponding migration and payload values are JSON primitives (str/int/float/bool/list/dict, isoformat dates)","Retry once if the failure was a transient connection issue"],"exampleFix":"// before\ndata = {\"created_at\": datetime.utcnow()}\nawait repo_update(record_id, data)\n// after\ndata = {\"created_at\": datetime.utcnow().isoformat()}\nawait repo_update(record_id, data)","handlingStrategy":"try-catch","validationCode":"existing = await repo_query(\"SELECT id FROM type::table($t) WHERE id = $id\", {'t': table, 'id': rid})\nif not existing:\n    skip update  # record gone","typeGuard":null,"tryCatchPattern":"try:\n    await repo_update(record_id, data)\nexcept RuntimeError as e:\n    if 'not found' in str(e):\n        return None  # treat as already deleted\n    raise","preventionTips":["Read the embedded cause text — repo_update includes it","Normalize payloads (isoformat dates, str enums) before update","Handle not-found as a benign case in concurrent workflows"],"tags":["database","surrealdb","update","schema"],"backgroundTag":"database-update-failed","analyzedSha":"a7de90d38aaf18ee85fd661854d35c11e44613e2","analyzedAt":"2026-08-27T02:39:58.166Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}