Skip to content

ctx_expand can't recover cleared file and image parts; it returns only "[file] name" #780

Open

Description

@null-axiom

Magic Context: 0.49.20 (ctx-expand render code unchanged through 0.49.22) · Host: OpenCode 2 (2.1.4-based)

When a file or image part (a pasted screenshot, an attached file) is cleared from context, ctx_expand(tag=N) can't bring it back. It returns only a label.

In src/tools/ctx-expand (published dist/v2/context-*.js), renderItemByTag resolves a non-tool tag to its message part and passes it to renderPartFull, which for type: "file" returns:

return `  [file]${name ? ` ${name}` : ""}`;

ctx_expand(message=N) goes through the same renderer. So the model gets [file] screenshot.png and none of the content, even though OpenCode still has the part (url/data) in stored history.

Scale in one long session: about 250 cleared file tags (196 dropped, 59 compacted), up to ~384 KB each, mostly screenshots the user pasted to show a bug.

Every other tag type recovers fine. I sampled 106 cleared tool outputs and 201 text tags: all matched the host's stored content byte for byte.

Suggestion: for file parts, return the attachment itself (OpenCode tool results can carry file attachments) or at least its stored path/URL and media type, so the model can re-open it. If that's out of scope, saying "content not recoverable, re-attach it" would at least stop the model treating the label as the content.

Source reading plus DB counts; I didn't capture a live ctx_expand of a file tag.

Activity

  1. magic-alfonso commented on Oct 25, 2026

    @magic-alfonso

    Thanks for the precise trace, you're right. renderPartFull in packages/plugin/src/tools/ctx-expand/render.ts returns only [file] <filename or url> for file parts, on both the tag=N and message=N paths, so a cleared screenshot or attachment comes back as a label with none of its content. Every other part type recovers in full, as your sample shows.

    The worse half of this is the one you named: the label reads like the content. At minimum, the model needs to be told plainly that the file wasn't recovered and to ask for it again. Whether we can hand the attachment itself back, or its stored path and media type, depends on the host. OpenCode 2 tool results can carry attachments, but Pi and OpenCode 1 differ, so we'll decide the shape across all hosts together.

    We're holding new fix work for a short while to finish a larger change, so this one is queued. We'll post here when it's picked up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions