Skip to content

Large base64 image in SessionNotification causes decode failure #39

@louis030195

Description

@louis030195

Description

When a session/update notification contains a large base64-encoded image (e.g., screenshots from MCP tools), the notification fails to decode and is silently dropped.

Error Log

[ERROR] [agent_client_protocol::rpc:237] failed to decode Some(RawValue({"type":"image","data":"iVBORw0KGgoAAAANSUhEUgAAB4AAAAQ...}))

Location

The error occurs in src/agent-client-protocol/src/rpc.rs line 237:

match Local::decode_notification(method, message.params) {
    Ok(notification) => { ... }
    Err(err) => {
        log::error!("failed to decode {:?}: {err}", message.params);  // <-- here
    }
}

Steps to Reproduce

  1. Have an MCP server return a large screenshot (e.g., 1920x1080 PNG, ~2-5MB base64)
  2. Agent sends this as ContentBlock::Image in a SessionNotification
  3. Client fails to decode the notification

Root Cause Analysis

The decode_notification function calls serde_json::from_str() on the params. For very large base64 strings in ImageContent.data, this can fail due to:

  1. BufReader::read_line() potentially having limits on line size
  2. Memory allocation issues with huge JSON strings
  3. The JSON being truncated somewhere in the stdio transport

Expected Behavior

Large image content should either:

  1. Successfully decode (preferred)
  2. Return a structured error that can be handled gracefully
  3. Have documented size limits in the schema

Actual Behavior

The notification is silently dropped with only a log error. The client never receives the image data.

Environment

  • Crate version: 0.9.x
  • Platform: Windows (also likely affects other platforms)
  • Use case: Desktop app using ACP to communicate with claude-code-acp, receiving screenshots from terminator MCP server

Suggested Solutions

  1. Increase/remove buffer limits in the RPC layer
  2. Add streaming support for large payloads
  3. Document maximum payload sizes
  4. Return the error to the caller instead of silently dropping

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