{"record":{"id":"77fc3bea5a428db9","repo":"OpenBMB/ChatDev","slug":"failed-to-copy-workflow-file","errorCode":null,"errorMessage":"Failed to copy workflow file","messagePattern":"Failed to copy workflow file","errorType":"exception","errorClass":"WorkflowExecutionError","httpStatus":null,"severity":"error","filePath":"server/services/workflow_storage.py","lineNumber":196,"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        target_path.write_text(source_path.read_text(encoding=\"utf-8\"), encoding=\"utf-8\")\n    except Exception as exc:\n        logger.log_exception(exc, f\"Failed to copy workflow file {source_safe} to {target_safe}\")\n        raise WorkflowExecutionError(\n            \"Failed to copy workflow file\",\n            details={\"source\": source_safe, \"target\": target_safe},\n        )\n\n    logger.info(\n        \"Workflow file copied\",\n        log_type=LogType.WORKFLOW,\n        source=source_safe,\n        target=target_safe,\n        action=\"copy\",\n    )\n","sourceCodeStart":178,"sourceCodeEnd":208,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/server/services/workflow_storage.py#L178-L208","documentation":"copy_workflow reads the source file and writes it to the target inside one try/except; any IO failure (source unreadable, target unwritable, disk full) is logged and re-raised as WorkflowExecutionError with source/target details.","triggerScenarios":"Permissions changed between the existence check and the read/write; source deleted concurrently (TOCTOU); disk full; read-only volume for the target.","commonSituations":"Container with read-only workflows mount; concurrent deletion; quota exhausted.","solutions":["Check logs for the underlying exception","Verify read permission on source and write permission on the directory","Retry once after re-validating both files' existence","Free disk space"],"exampleFix":"# before\ncopy_workflow_file(sid, src, tgt)\n# after\ntry:\n    copy_workflow_file(sid, src, tgt)\nexcept WorkflowExecutionError:\n    if not workflow_exists(sid, src):\n        raise ResourceGone(src)\n    raise","handlingStrategy":"try-catch","validationCode":"assert (directory/src).is_file() and os.access(directory, os.W_OK)","typeGuard":null,"tryCatchPattern":"try:\n    copy_workflow_file(sid, src, tgt)\nexcept WorkflowExecutionError as e:\n    handle_io_failure(e.details)  # check source gone vs perms vs disk","preventionTips":["Verify read+write perms at startup","Retry once after re-validating existence","Monitor disk space"],"tags":["filesystem","workflow","copy","io"],"backgroundTag":"file-copy-failed","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}