{"record":{"id":"f1a0b6fad2ff7f7c","repo":"siyuan-note/siyuan","slug":"image-attachment-request-limit-exceeded-at-most","errorCode":null,"errorMessage":"image attachment request limit exceeded: at most %d images and %d bytes","messagePattern":"image attachment request limit exceeded: at most (.+?) images and (.+?) bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/agent/attachments.go","lineNumber":62,"sourceCode":"\texpiresAt time.Time\n}\n\nvar imageInputUnsupportedCache sync.Map\n\nfunc mergeAgentAttachments(current []AgentAttachment, attachments []mcptools.ModelAttachment) (merged, added []AgentAttachment, err error) {\n\timageCount := len(current)\n\ttotalBytes := 0\n\tfor _, attachment := range current {\n\t\ttotalBytes += len(attachment.Data)\n\t}\n\n\tadded = make([]AgentAttachment, 0, len(attachments))\n\tfor _, attachment := range attachments {\n\t\tif attachment.Type != \"image\" || len(attachment.Data) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif imageCount >= maxAgentImagesPerRequest || totalBytes+len(attachment.Data) > maxAgentImageBytesPerRequest {\n\t\t\treturn current, nil, fmt.Errorf(\n\t\t\t\t\"image attachment request limit exceeded: at most %d images and %d bytes\",\n\t\t\t\tmaxAgentImagesPerRequest, maxAgentImageBytesPerRequest,\n\t\t\t)\n\t\t}\n\t\tadded = append(added, AgentAttachment{\n\t\t\tType:       attachment.Type,\n\t\t\tData:       attachment.Data,\n\t\t\tMIMEType:   attachment.MIMEType,\n\t\t\tPath:       attachment.Path,\n\t\t\tDocumentID: attachment.DocumentID,\n\t\t\tDetail:     attachment.Detail,\n\t\t\tWidth:      attachment.Width,\n\t\t\tHeight:     attachment.Height,\n\t\t})\n\t\timageCount++\n\t\ttotalBytes += len(attachment.Data)\n\t}\n\tmerged = append(append([]AgentAttachment(nil), current...), added...)","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/agent/attachments.go#L44-L80","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reduce the number of images attached per message to stay within maxAgentImagesPerRequest.","Compress or downscale screenshots before attaching so total bytes stay under maxAgentImageBytesPerRequest.","Split the attachments across multiple messages/requests.","If limits are legitimately too small for your workflow, raise maxAgentImagesPerRequest/maxAgentImageBytesPerRequest within provider limits."],"exampleFix":"// before: attaches 12 large screenshots at once\nawait mergeAgentAttachments(current, screenshots) // throws\n// after: chunk the batch under the limits\nconst limit = 5\nfor (let i = 0; i < screenshots.length; i += limit) {\n  current = await mergeAgentAttachments(current, screenshots.slice(i, i + limit))\n}","handlingStrategy":"validation","validationCode":"function isWithinImageLimits(attachments) {\n  const imgs = attachments.filter(a => a.type === \"image\" && a.data?.length)\n  const bytes = imgs.reduce((n, a) => n + a.data.length, 0)\n  return imgs.length <= MAX_IMAGES && bytes <= MAX_BYTES\n}","typeGuard":null,"tryCatchPattern":"const [next, added, err] = await mergeAgentAttachments(current, attachments)\nif (err) {\n  // trim or compress the batch, then retry with fewer/smaller images\n}","preventionTips":["Count and size-check image attachments client-side before merging.","Compress/downscale screenshots before attaching.","Split large image batches across multiple requests.","Keep plugin attachment code aware of maxAgentImagesPerRequest/maxAgentImageBytesPerRequest."],"tags":["attachments","images","limit","agent"],"backgroundTag":"payload-too-large","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}