Skip to content

Attachment filename mismatch: metadata reports inbox path but media/ directory uses different GUID filename #1683

Description

@Aaronontheweb

Problem

When a user sends an image attachment via a chat channel (Slack, Discord, Mattermost, etc.), the session.media_dir context provided to the agent contains a path that does not match the actual filename stored in the media/ directory. The agent must discover the real filename by listing the directory, which wastes turns and creates confusion.

What the agent sees

The attachment metadata contains an inbox/ path:

inbox/screenshot_hist_3b27758edaa7f4fa.png

What actually exists in media/

The file was copied to media/ with a completely different GUID-based filename:

media/c0bbe128bd374eaf81e0c582ab390712.png

The agent has no way to derive the media/ filename from the metadata. It must ls the media/ directory to find it.

Root Cause

Three independent naming schemes operate simultaneously across the attachment pipeline:

  1. Inbox live download — preserves the original channel filename (image.png)
  2. Inbox historical backfill — generates a hash-based stable name (image_hist_<sha256_prefix>.png)
  3. Media/ inline copy — generates a GUID-based name (<guid_no_dashes>.png)

When inlined=true, SessionMediaStore.CopyFile calls Guid.NewGuid().ToString("N") to generate the media/ filename, completely discarding the source filename from step 2. The attachment metadata reports the inbox path, but the actual file the agent accesses lives at a different path with a different name. The pipeline runs with zero warnings or errors.

Reproduction

  1. Send an image attachment (e.g., screenshot.png) through any chat channel to the agent
  2. Check the session.media_dir context the agent receives — it contains an inbox/ path like inbox/screenshot_hist_3b27758edaa7f4fa.png
  3. The agent attempts to access the file at that path relative to media/ — the file does not exist there
  4. The agent must list the media/ directory to discover the actual GUID-based filename

Scope

This is not channel-specific. The shared components affected are:

File Role
src/Netclaw.Channels/AttachmentIngressFormatting.cs BuildAcceptedProjectionAsync constructs the attachment metadata with the inbox path
src/Netclaw.Channels/HistoricalAttachmentInbox.cs PromoteOrReuse generates hash-based inbox filenames for historical backfill
src/Netclaw.Actors/Protocol/SessionMediaStore.cs CreateMediaFileName / CopyFile generates GUID-based media filenames
src/Netclaw.Actors/SessionToolExecutionPipeline.cs MaterializeModelInputFiles performs the inbox-to-media copy

All chat channels (Slack, Discord, Mattermost) use these shared components equally. The naming mismatch affects every channel that sends attachments.

Impact

  • Agent cannot trust the path reported in attachment metadata
  • Forces the agent to perform directory listings to find the actual file — wasting turns and context window
  • Creates confusing behavior where the agent references a path that doesn't match reality
  • No log warnings or errors — the entire pipeline succeeds silently despite the mismatch
  • Degrades the agent's ability to work reliably with user attachments

Suggested Fix

The cleanest fix would be for SessionMediaStore.CopyFile to preserve the source filename (without the directory path) instead of generating a new GUID. This would make the media/ filename match what's reported in the attachment metadata.

Alternative: after the inline copy completes, update the attachment metadata to report the actual media/ path and filename. This keeps the GUID scheme but ensures the agent receives accurate paths.

Either approach would eliminate the need for the agent to discover filenames through directory listings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingchannelsDiscord, Slack, and other channels.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions