OpenBMB/ChatDev · error · KeyError

Attachment '{attachment_id}' not found

Error message

Attachment '{attachment_id}' not found

What it means

AttachmentManager.update_remote_file_id raises KeyError when the attachment_id is not in the in-memory _records registry. It is called after uploading to a provider to store the returned remote file id, so the record must have been registered earlier in the same manager instance.

Source

Thrown at utils/attachments.py:217

            size=size,
            remote_file_id=remote_file_id,
        )
        record = AttachmentRecord(ref=ref, kind=kind, description=description, extra=extra or {})
        self._records[attachment_id] = record
        if persist:
            self._persistent_ids.add(attachment_id)
            self._save_manifest()
        else:
            self._persistent_ids.discard(attachment_id)
        if ref.sha256:
            self._hash_index[ref.sha256] = attachment_id
        return record

    def update_remote_file_id(self, attachment_id: str, remote_file_id: str) -> None:
        """Attach a provider file_id to an existing record (after upload)."""
        record = self._records.get(attachment_id)
        if not record:
            raise KeyError(f"Attachment '{attachment_id}' not found")
        record.ref.remote_file_id = remote_file_id
        if attachment_id in self._persistent_ids:
            self._save_manifest()

    def get(self, attachment_id: str) -> AttachmentRecord | None:
        return self._records.get(attachment_id)

    def to_message_block(self, attachment_id: str) -> MessageBlock:
        record = self._records.get(attachment_id)
        if not record:
            raise KeyError(f"Attachment '{attachment_id}' not found")
        return record.as_message_block()

    def list_records(self) -> Dict[str, AttachmentRecord]:
        return dict(self._records)

    def export_manifest(self) -> Dict[str, Any]:
        return {

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Confirm the registration call (register_file/register_bytes) succeeded and use the id it returned
  2. Use the same AttachmentManager instance for register and update
  3. Catch KeyError and re-register/re-upload the attachment to get a fresh id

Example fix

# before
manager.update_remote_file_id(att_id, remote_id)
# after
if manager.get(att_id) is None:
    raise UnknownAttachment(att_id)
manager.update_remote_file_id(att_id, remote_id)
Defensive patterns

Strategy: validation

Validate before calling

if manager.get(attachment_id) is None:
    raise UnknownAttachment(attachment_id)

Type guard

def has_attachment(m, aid: str) -> bool:
    return m.get(aid) is not None

Try / catch

try:
    manager.update_remote_file_id(aid, rid)
except KeyError:
    rec = re_register_source(); manager.update_remote_file_id(rec.attachment_id, rid)

Prevention

When it happens

Trigger: Calling update_remote_file_id after a server restart (records are in-memory), with a typo'd id, or before register_file/register_bytes created the record.

Common situations: State lost across process restarts or between manager instances; multi-worker deployment where registration and update hit different workers; race where the record is evicted before the upload completes.

Related errors


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