{"record":{"id":"a76053c0ca54b770","repo":"larksuite/cli","slug":"remove-attachment-requires-target-with-at-least-on","errorCode":null,"errorMessage":"remove_attachment requires target with at least one of part_id, cid, or token","messagePattern":"remove_attachment requires target with at least one of part_id, cid, or token","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/model.go","lineNumber":320,"sourceCode":"\t\t\treturn fmt.Errorf(\"set_header requires name\")\n\t\t}\n\t\tif strings.ContainsAny(op.Name, \":\\r\\n\") {\n\t\t\treturn fmt.Errorf(\"set_header: header name must not contain ':', CR, or LF\")\n\t\t}\n\t\tif strings.ContainsAny(op.Value, \"\\r\\n\") {\n\t\t\treturn fmt.Errorf(\"set_header: header value must not contain CR or LF\")\n\t\t}\n\tcase \"remove_header\":\n\t\tif strings.TrimSpace(op.Name) == \"\" {\n\t\t\treturn fmt.Errorf(\"remove_header requires name\")\n\t\t}\n\tcase \"add_attachment\":\n\t\tif strings.TrimSpace(op.Path) == \"\" {\n\t\t\treturn fmt.Errorf(\"add_attachment requires path\")\n\t\t}\n\tcase \"remove_attachment\":\n\t\tif !op.Target.hasAnyKey() {\n\t\t\treturn fmt.Errorf(\"remove_attachment requires target with at least one of part_id, cid, or token\")\n\t\t}\n\tcase \"add_inline\":\n\t\tif strings.TrimSpace(op.Path) == \"\" {\n\t\t\treturn fmt.Errorf(\"add_inline requires path\")\n\t\t}\n\t\tif strings.TrimSpace(op.CID) == \"\" {\n\t\t\treturn fmt.Errorf(\"add_inline requires cid\")\n\t\t}\n\tcase \"replace_inline\":\n\t\tif !op.Target.hasKey() {\n\t\t\treturn fmt.Errorf(\"replace_inline requires target with at least one of part_id or cid\")\n\t\t}\n\t\tif strings.TrimSpace(op.Path) == \"\" {\n\t\t\treturn fmt.Errorf(\"replace_inline requires path\")\n\t\t}\n\tcase \"remove_inline\":\n\t\tif !op.Target.hasKey() {\n\t\t\treturn fmt.Errorf(\"remove_inline requires target with at least one of part_id or cid\")","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/model.go#L302-L338","documentation":"A `remove_attachment` draft operation must identify which attachment to remove via at least one of `part_id`, `cid`, or `token` in its `target` object. If the target is empty or none of those keys is set, the validator rejects the op because the attachment to remove is ambiguous.","triggerScenarios":"Submitting `{\"op\":\"remove_attachment\"}` with no `target`, with `target: {}`, or with other keys (e.g. filename) that are not one of part_id/cid/token — target.hasAnyKey() checks exactly those three keys.","commonSituations":"Automation that clears attachments without first reading the draft to learn part_ids/cids; JSON where the target was nested one level too deep; confusing remove_attachment (needs target) with add_attachment (needs path).","solutions":["Add at least one of `part_id`, `cid`, or `token` inside the operation's `target` object","Fetch the draft first to obtain a valid part_id, cid, or token for the attachment you want to remove","Verify the target object is correctly nested in the JSON and not flattened to the op level"],"exampleFix":"// before\n{\"op\":\"remove_attachment\"}\n// after\n{\"op\":\"remove_attachment\",\"target\":{\"cid\":\"inline-logo@1\"}}","handlingStrategy":"validation","validationCode":"if !op.Target.hasAnyKey() {\n    return fmt.Errorf(\"remove_attachment requires target with at least one of part_id, cid, or token\")\n}","typeGuard":"func targetIdentified(t Target) bool { return t.hasAnyKey() }","tryCatchPattern":null,"preventionTips":["Read the draft first to obtain part_id/cid/token before removing an attachment","Never submit remove_attachment with an empty or partially-populated target","Keep target keys (part_id/cid/token) inside the target object, not at the op level"],"tags":["validation","mail","draft","missing-field"],"backgroundTag":"missing-required-argument","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"}