OpenBMB/ChatDev · error · ValueError

Attachment missing data for persistence

Error message

Attachment missing data for persistence

What it means

The attachment has neither a remote_file_id, nor a local_path, nor data_bytes to write — nothing can be persisted. Raised by _persist_single_attachment when every data source is absent.

Source

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

        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)
        else:
            raise ValueError("Attachment missing data for persistence")

        record = store.register_file(
            target_path,
            kind=block.type,
            display_name=attachment.name or target_path.name,
            mime_type=attachment.mime_type,
            attachment_id=attachment.attachment_id,
            copy_file=False,
            persist=True,
        )
        block.attachment = record.ref

    def _decode_data_uri(self, data_uri: Optional[str]) -> Optional[bytes]:
        if not data_uri:
            return None
        if not data_uri.startswith("data:"):
            return None
        header, _, payload = data_uri.partition(",")

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Verify the producing node actually attached data (data_uri, local_path, or bytes)
  2. Check message cloning/serialization paths don't strip attachment payloads
  3. If the attachment is intentionally empty, skip persistence for blocks without data
Defensive patterns

Strategy: validation

Validate before calling

a = block.attachment
has_data = a and (a.remote_file_id or a.local_path or a.data_uri or getattr(a, 'data_bytes', None))
if not has_data:
    continue  # skip empty attachment blocks

Type guard

def has_persistable_data(a) -> bool:
    return bool(a and (a.remote_file_id or a.local_path or a.data_uri))

Prevention

When it happens

Trigger: Message block references an attachment whose ref was never populated (no data_uri, no local_path, no bytes, no remote id).

Common situations: LLM emitting an attachment block with only metadata; upstream node dropped attachment payloads when cloning messages; deserialization losing binary fields.

Related errors


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