{"record":{"id":"470a55d873e0413d","repo":"OpenBMB/ChatDev","slug":"failed-to-rename-workflow-file","errorCode":null,"errorMessage":"Failed to rename workflow file","messagePattern":"Failed to rename workflow file","errorType":"exception","errorClass":"WorkflowExecutionError","httpStatus":null,"severity":"error","filePath":"server/services/workflow_storage.py","lineNumber":140,"sourceCode":"        raise ResourceNotFoundError(\n            \"Workflow file not found\",\n            resource_type=\"workflow\",\n            resource_id=source_safe,\n        )\n\n    if target_path.exists():\n        raise ResourceConflictError(\n            \"Target workflow already exists\",\n            resource_type=\"workflow\",\n            resource_id=target_safe,\n        )\n\n    logger = get_server_logger()\n    try:\n        source_path.rename(target_path)\n    except Exception as exc:\n        logger.log_exception(exc, f\"Failed to rename workflow file {source_safe} to {target_safe}\")\n        raise WorkflowExecutionError(\n            \"Failed to rename workflow file\",\n            details={\"source\": source_safe, \"target\": target_safe},\n        )\n\n    try:\n        new_workflow_id = Path(target_safe).stem\n        content = target_path.read_text(encoding=\"utf-8\")\n        updated = _update_workflow_id(content, new_workflow_id)\n        if updated != content:\n            target_path.write_text(updated, encoding=\"utf-8\")\n    except Exception as exc:\n        logger.log_exception(exc, f\"Failed to update workflow id after rename to {target_safe}\")\n        raise WorkflowExecutionError(\n            \"Failed to update workflow id after rename\",\n            details={\"target\": target_safe},\n        )\n\n    logger.info(","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/server/services/workflow_storage.py#L122-L158","documentation":"rename_workflow wraps Path.rename in try/except and re-raises WorkflowExecutionError with source/target details when the OS rename fails (permissions, cross-device link, file vanished between the exists check and the rename). The original exception is logged.","triggerScenarios":"Directory not writable; source removed by a concurrent process after the existence check (TOCTOU); target created by a concurrent request between check and rename; EXDEV if paths resolve across mount points via symlinks.","commonSituations":"Concurrent API calls racing; read-only container volume; workflows directory replaced by a symlink to another filesystem.","solutions":["Check server logs for the underlying OSError (errno tells you which case)","Retry after confirming both source exists and target is free (race may have cleared)","Fix directory permissions / mount configuration"],"exampleFix":"# before\nrename_workflow_file(sid, src, tgt)\n# after\ntry:\n    rename_workflow_file(sid, src, tgt)\nexcept WorkflowExecutionError:\n    refresh_and_retry_once()  # re-check existence/conflict then retry","handlingStrategy":"retry","validationCode":"import os\nassert (directory/src).exists() and not (directory/tgt).exists()","typeGuard":null,"tryCatchPattern":"try:\n    rename_workflow_file(sid, src, tgt)\nexcept WorkflowExecutionError:\n    if exists(src) and not exists(tgt):\n        rename_workflow_file(sid, src, tgt)  # one retry after race clears\n    else:\n        raise","preventionTips":["Serialize workflow mutations per session (lock)","Check server logs for underlying OSError errno","Retry once on transient races only"],"tags":["filesystem","workflow","rename","race-condition"],"backgroundTag":"filesystem-rename-failed","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}