OpenBMB/ChatDev · error · RuntimeError

Workspace or node context missing for attachment persistence

Error message

Workspace or node context missing for attachment persistence

What it means

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.

Source

Thrown at runtime/node/executor/agent_executor.py:1103

    def _persist_single_attachment(self, store: Any, block: MessageBlock, node_id: str) -> None:
        attachment = block.attachment
        if attachment is None:
            return
        if attachment.remote_file_id and not attachment.data_uri and not attachment.local_path:
            record = store.register_remote_file(
                remote_file_id=attachment.remote_file_id,
                name=attachment.name or attachment.attachment_id or "remote_file",
                mime_type=attachment.mime_type,
                size=attachment.size,
                kind=block.type,
                attachment_id=attachment.attachment_id,
            )
            block.attachment = record.ref
            return

        workspace_root = self.context.global_state.get("python_workspace_root")
        if workspace_root is None or not node_id:
            raise RuntimeError("Workspace or node context missing for attachment persistence")

        target_dir = workspace_root / "generated" / node_id
        target_dir.mkdir(parents=True, exist_ok=True)

        inferred_mime = attachment.mime_type or self._guess_mime_from_data_uri(attachment.data_uri)
        attachment.mime_type = inferred_mime

        data_bytes = self._decode_data_uri(attachment.data_uri) if attachment.data_uri else None
        target_path = None

        if data_bytes is None and attachment.local_path:
            target_path = target_dir / (attachment.name or self._make_generated_filename(attachment))
            import shutil
            shutil.copy2(attachment.local_path, target_path)
        elif data_bytes is not None:
            target_path = target_dir / (attachment.name or self._make_generated_filename(attachment))
            with open(target_path, "wb") as handle:
                handle.write(data_bytes)

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Ensure the workflow bootstrap sets context.global_state['python_workspace_root'] to a Path
  2. Run the node through the normal workflow engine so workspace provisioning happens
  3. If embedding the executor manually, populate global_state and use non-empty node ids

Example fix

# before
context.global_state = {}

# after
context.global_state['python_workspace_root'] = Path('/srv/workspaces/run-1')
Defensive patterns

Strategy: validation

Validate before calling

root = context.global_state.get('python_workspace_root')
assert root is not None and node_id, 'workspace context missing'

Prevention

When it happens

Trigger: 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).

Common situations: Running the executor outside the standard workflow bootstrap (unit tests, embedded usage); workspace provisioning step skipped or failed earlier; misconfigured runtime context.

Related errors


AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27). Data as JSON: /api/errors/b2d758349bdd6337. Report an issue: GitHub.