siyuan-note/siyuan · error

image attachment request limit exceeded: at most %d images a

Error message

image attachment request limit exceeded: at most %d images and %d bytes

What it means

mergeAgentAttachments() returns an fmt.Errorf with this template when adding another image would exceed the hard caps: maxAgentImagesPerRequest (4) or maxAgentImageBytesPerRequest (20 MiB). Both imageCount (number of existing image attachments) and totalBytes are accumulated across current+added attachments before the guard.

Source

Thrown at kernel/agent/attachments.go:61

	expiresAt time.Time
}

var imageInputUnsupportedCache sync.Map

func mergeAgentAttachments(current []AgentAttachment, attachments []mcptools.ModelAttachment) (merged, added []AgentAttachment, err error) {
	imageCount := len(current)
	totalBytes := 0
	for _, attachment := range current {
		totalBytes += len(attachment.Data)
	}

	added = make([]AgentAttachment, 0, len(attachments))
	for _, attachment := range attachments {
		if attachment.Type != "image" || len(attachment.Data) == 0 {
			continue
		}
		if imageCount >= maxAgentImagesPerRequest || totalBytes+len(attachment.Data) > maxAgentImageBytesPerRequest {
			return current, nil, fmt.Errorf(
				"image attachment request limit exceeded: at most %d images and %d bytes",
				maxAgentImagesPerRequest, maxAgentImageBytesPerRequest,
			)
		}
		added = append(added, AgentAttachment{
			Type:       attachment.Type,
			Data:       attachment.Data,
			MIMEType:   attachment.MIMEType,
			Path:       attachment.Path,
			DocumentID: attachment.DocumentID,
			Detail:     attachment.Detail,
			Width:      attachment.Width,
			Height:     attachment.Height,
		})
		imageCount++
		totalBytes += len(attachment.Data)
	}
	merged = append(append([]AgentAttachment(nil), current...), added...)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Reduce the number of images to at most 4 per agent request (downscale or omit extras before sending).
  2. Compress/resize each image so total bytes stay under 20 MiB.
  3. Split the request into multiple turns if more than 4 images are genuinely needed.
  4. If higher limits are operationally required, override the constants in a fork (maxAgentImagesPerRequest / maxAgentImageBytesPerRequest in kernel/agent/attachments.go) and document the trade-off.

Example fix

// before
req := appendImages(req, allImages) // 6 images, 30 MiB
// after
const maxN = 4
if len(allImages) > maxN { allImages = allImages[:maxN] }
for _, img := range allImages { img = resizeTo(img, 1920, jpegQuality(85)) }
req := appendImages(req, allImages)
Defensive patterns

Strategy: validation

Validate before calling

const maxImages = 4;
const maxBytes = 20 * 1024 * 1024;
if (imageAttachments.length > maxImages) imageAttachments = imageAttachments.slice(0, maxImages);
let bytes = imageAttachments.reduce((n, a) => n + a.Data.length, 0);
while (bytes > maxBytes && imageAttachments.length) { bytes -= imageAttachments.pop().Data.length; }

Try / catch

merged, added, err := mergeAgentAttachments(current, incoming)
if err != nil {
    if strings.Contains(err.Error(), 'image attachment request limit exceeded') { /* drop or resize and retry */ }
    return err
}

Prevention

When it happens

Trigger: An agent turn attaches a 5th image, or the cumulative size of all image attachments on the request exceeds 20 MiB; calling the agent endpoint with several high-resolution screenshots pasted in one turn; attachments merged from multiple tool results in a single turn.

Common situations: User drags 5+ photos into the chat; an image-heavy block reference adds screenshots that push the byte total over 20 MiB; tool returns base64 images that cumulatively exceed the cap; very large PNGs from a screen-capture tool.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/f1a0b6fad2ff7f7c. Report an issue: GitHub.