{"record":{"id":"b371b2ca372f88e7","repo":"larksuite/cli","slug":"attachment-part-q-not-found","errorCode":null,"errorMessage":"attachment part %q not found","messagePattern":"attachment part %q not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":756,"sourceCode":"\tif !isInlinePart(part) {\n\t\treturn fmt.Errorf(\"part %q is not an inline MIME part\", partID)\n\t}\n\tif snapshot.Body == nil || snapshot.Body.PartID == partID {\n\t\treturn fmt.Errorf(\"cannot remove root MIME part\")\n\t}\n\tif !removePart(snapshot.Body, partID) {\n\t\treturn fmt.Errorf(\"inline part %q not found\", partID)\n\t}\n\treturn nil\n}\n\nfunc removeAttachment(snapshot *DraftSnapshot, partID string) error {\n\tif snapshot.Body == nil {\n\t\treturn fmt.Errorf(\"draft has no MIME body\")\n\t}\n\tpart := findPart(snapshot.Body, partID)\n\tif part == nil {\n\t\treturn fmt.Errorf(\"attachment part %q not found\", partID)\n\t}\n\tif strings.EqualFold(part.ContentDisposition, \"inline\") || part.ContentID != \"\" {\n\t\treturn fmt.Errorf(\"part %q is an inline MIME part; use remove_inline\", partID)\n\t}\n\tif snapshot.Body.PartID == partID {\n\t\treturn fmt.Errorf(\"cannot remove root MIME part\")\n\t}\n\tremoved := removePart(snapshot.Body, partID)\n\tif !removed {\n\t\treturn fmt.Errorf(\"attachment part %q not found\", partID)\n\t}\n\treturn nil\n}\n\nfunc removePart(parent *Part, targetPartID string) bool {\n\tfor idx, child := range parent.Children {\n\t\tif child == nil {\n\t\t\tcontinue","sourceCodeStart":738,"sourceCodeEnd":774,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L738-L774","documentation":"This error means the draft's MIME snapshot has a body, but no MIME part with the requested part_id exists, so the attachment removal cannot proceed. removeAttachment is a mail draft patch operation that looks up the target part with findPart before deleting it. The library throws it to prevent silently ignoring a remove op that references a nonexistent part.","triggerScenarios":"Calling the mail draft patch remove_attachment operation with a target part_id that is not present in the current draft MIME tree, or one that was already removed by a previous op in the same patch batch.","commonSituations":"Stale part IDs from an earlier draft read after the draft was regenerated; double-applying the same patch; typos in part_id; removing attachments from a draft whose body was replaced between reads.","solutions":["Re-read the draft to get the current MIME snapshot and use a part_id that exists","Check whether the op already ran earlier in the same patch and remove the duplicate op","Verify part_id spelling/format against the draft's listed attachment parts","Use the inline-part remove operation if the part is actually an inline part (see related error)"],"exampleFix":"// before\n{\"op\":\"remove_attachment\",\"target\":{\"part_id\":\"old-stale-id\"}}\n// after — re-fetch draft, list attachments, use a live part_id\n{\"op\":\"remove_attachment\",\"target\":{\"part_id\":\"current-attachment-part-id\"}}","handlingStrategy":"validation","validationCode":"func canRemoveAttachment(snap *DraftSnapshot, partID string) bool {\n\tpart := findPart(snap.Body, partID)\n\treturn snap.Body != nil && part != nil && !strings.EqualFold(part.ContentDisposition, \"inline\") && part.ContentID == \"\" && snap.Body.PartID != partID\n}","typeGuard":"func isAttachmentPart(p *Part) bool {\n\treturn p != nil && !strings.EqualFold(p.ContentDisposition, \"inline\") && p.ContentID == \"\"\n}","tryCatchPattern":"if err := applyOp(snap, op); err != nil && strings.Contains(err.Error(), \"not found\") {\n\t// re-fetch draft snapshot and re-resolve part_id before retrying\n}","preventionTips":["Always re-read the draft snapshot immediately before patching","Track part IDs per snapshot version; never reuse IDs across reads","Deduplicate ops within one patch batch","Classify parts (attachment vs inline) before choosing the op"],"tags":["mail","draft","mime","not-found"],"backgroundTag":"mime-part-not-found","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}