larksuite/cli · error
remove_attachment requires target with at least one of part_
Error message
remove_attachment requires target with at least one of part_id, cid, or token
What it means
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.
Source
Thrown at shortcuts/mail/draft/model.go:320
return fmt.Errorf("set_header requires name")
}
if strings.ContainsAny(op.Name, ":\r\n") {
return fmt.Errorf("set_header: header name must not contain ':', CR, or LF")
}
if strings.ContainsAny(op.Value, "\r\n") {
return fmt.Errorf("set_header: header value must not contain CR or LF")
}
case "remove_header":
if strings.TrimSpace(op.Name) == "" {
return fmt.Errorf("remove_header requires name")
}
case "add_attachment":
if strings.TrimSpace(op.Path) == "" {
return fmt.Errorf("add_attachment requires path")
}
case "remove_attachment":
if !op.Target.hasAnyKey() {
return fmt.Errorf("remove_attachment requires target with at least one of part_id, cid, or token")
}
case "add_inline":
if strings.TrimSpace(op.Path) == "" {
return fmt.Errorf("add_inline requires path")
}
if strings.TrimSpace(op.CID) == "" {
return fmt.Errorf("add_inline requires cid")
}
case "replace_inline":
if !op.Target.hasKey() {
return fmt.Errorf("replace_inline requires target with at least one of part_id or cid")
}
if strings.TrimSpace(op.Path) == "" {
return fmt.Errorf("replace_inline requires path")
}
case "remove_inline":
if !op.Target.hasKey() {
return fmt.Errorf("remove_inline requires target with at least one of part_id or cid")View on GitHub (pinned to 7fd6ef3c07)
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
Example fix
// before
{"op":"remove_attachment"}
// after
{"op":"remove_attachment","target":{"cid":"inline-logo@1"}} Defensive patterns
Strategy: validation
Validate before calling
if !op.Target.hasAnyKey() {
return fmt.Errorf("remove_attachment requires target with at least one of part_id, cid, or token")
} Type guard
func targetIdentified(t Target) bool { return t.hasAnyKey() } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- add_attachment requires path
- add_inline requires path
- add_inline requires cid
- replace_inline requires target with at least one of part_id
- target must specify at least one of part_id or cid
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/a76053c0ca54b770.
Report an issue: GitHub.