{"record":{"id":"b2d758349bdd6337","repo":"OpenBMB/ChatDev","slug":"workspace-or-node-context-missing-for-attachment-p","errorCode":null,"errorMessage":"Workspace or node context missing for attachment persistence","messagePattern":"Workspace or node context missing for attachment persistence","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"runtime/node/executor/agent_executor.py","lineNumber":1103,"sourceCode":"    def _persist_single_attachment(self, store: Any, block: MessageBlock, node_id: str) -> None:\n        attachment = block.attachment\n        if attachment is None:\n            return\n        if attachment.remote_file_id and not attachment.data_uri and not attachment.local_path:\n            record = store.register_remote_file(\n                remote_file_id=attachment.remote_file_id,\n                name=attachment.name or attachment.attachment_id or \"remote_file\",\n                mime_type=attachment.mime_type,\n                size=attachment.size,\n                kind=block.type,\n                attachment_id=attachment.attachment_id,\n            )\n            block.attachment = record.ref\n            return\n\n        workspace_root = self.context.global_state.get(\"python_workspace_root\")\n        if workspace_root is None or not node_id:\n            raise RuntimeError(\"Workspace or node context missing for attachment persistence\")\n\n        target_dir = workspace_root / \"generated\" / node_id\n        target_dir.mkdir(parents=True, exist_ok=True)\n\n        inferred_mime = attachment.mime_type or self._guess_mime_from_data_uri(attachment.data_uri)\n        attachment.mime_type = inferred_mime\n\n        data_bytes = self._decode_data_uri(attachment.data_uri) if attachment.data_uri else None\n        target_path = None\n\n        if data_bytes is None and attachment.local_path:\n            target_path = target_dir / (attachment.name or self._make_generated_filename(attachment))\n            import shutil\n            shutil.copy2(attachment.local_path, target_path)\n        elif data_bytes is not None:\n            target_path = target_dir / (attachment.name or self._make_generated_filename(attachment))\n            with open(target_path, \"wb\") as handle:\n                handle.write(data_bytes)","sourceCodeStart":1085,"sourceCodeEnd":1121,"githubUrl":"https://github.com/OpenBMB/ChatDev/blob/4fb2db0ea90375ce1059f44fe03ffbd191a7a169/runtime/node/executor/agent_executor.py#L1085-L1121","documentation":"An attachment needs to be written to disk but the executor cannot resolve a destination: context.global_state lacks 'python_workspace_root' or the node_id is empty. Persistence is aborted rather than writing to an unknown location.","triggerScenarios":"Executing an agent node with attachments when the workspace root was never initialized in global state, or node_id is falsy (e.g. empty string id).","commonSituations":"Running the executor outside the standard workflow bootstrap (unit tests, embedded usage); workspace provisioning step skipped or failed earlier; misconfigured runtime context.","solutions":["Ensure the workflow bootstrap sets context.global_state['python_workspace_root'] to a Path","Run the node through the normal workflow engine so workspace provisioning happens","If embedding the executor manually, populate global_state and use non-empty node ids"],"exampleFix":"# before\ncontext.global_state = {}\n\n# after\ncontext.global_state['python_workspace_root'] = Path('/srv/workspaces/run-1')","handlingStrategy":"validation","validationCode":"root = context.global_state.get('python_workspace_root')\nassert root is not None and node_id, 'workspace context missing'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Bootstrap workspace state via the standard workflow engine","Assert required global_state keys in executor setup"],"tags":["attachments","workspace","missing-context"],"backgroundTag":"missing-runtime-context","analyzedSha":"4fb2db0ea90375ce1059f44fe03ffbd191a7a169","analyzedAt":"2026-08-27T14:35:29.622Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}