siyuan-note/siyuan · error

image attachment request limit exceeded: at most

Error message

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

What it means

Raised by mergeAgentAttachments when the batch of pending image attachments would exceed the per-request limits: maxAgentImagesPerRequest images or maxAgentImageBytesPerRequest total bytes. The entire oversized batch is rejected — current attachments are returned unchanged along with the error — so a single request never carries too many or too many bytes of image payloads.

Solutions

  1. Reduce the number of images attached per message to stay within maxAgentImagesPerRequest.
  2. Compress or downscale screenshots before attaching so total bytes stay under maxAgentImageBytesPerRequest.
  3. Split the attachments across multiple messages/requests.
  4. If limits are legitimately too small for your workflow, raise maxAgentImagesPerRequest/maxAgentImageBytesPerRequest within provider limits.

Example fix

// before: attaches 12 large screenshots at once
await mergeAgentAttachments(current, screenshots) // throws
// after: chunk the batch under the limits
const limit = 5
for (let i = 0; i < screenshots.length; i += limit) {
  current = await mergeAgentAttachments(current, screenshots.slice(i, i + limit))
}
Defensive patterns

Strategy: validation

Validate before calling

function isWithinImageLimits(attachments) {
  const imgs = attachments.filter(a => a.type === "image" && a.data?.length)
  const bytes = imgs.reduce((n, a) => n + a.data.length, 0)
  return imgs.length <= MAX_IMAGES && bytes <= MAX_BYTES
}

Try / catch

const [next, added, err] = await mergeAgentAttachments(current, attachments)
if (err) {
  // trim or compress the batch, then retry with fewer/smaller images
}

Prevention

When it happens

Trigger: In attachments.go (~line 62): the user (or a plugin) queues more images than maxAgentImagesPerRequest in one message, or the accumulated image bytes plus the new attachment's len(attachment.Data) exceed maxAgentImageBytesPerRequest while iterating image-type attachments.

Common situations: Dragging a large screenshot batch into the AI chat; pasting several high-resolution screenshots (each several MB) into one message; a plugin bulk-inserting images; lowering provider image limits while an old large batch is pending.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/f1a0b6fad2ff7f7c. Report an issue: GitHub.

Appendix: source

Thrown at kernel/agent/attachments.go:62

	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 9f775e8a12)