larksuite/cli · error

no part with cid %q found

Error message

no part with cid %q found

What it means

resolveTarget translates an inline-target's cid into a part_id by searching the MIME tree with findPartByCID; when no part carries a matching Content-ID, it returns this error. CIDs are matched after trimming surrounding angle brackets, but the cid must otherwise correspond to an existing inline part in the current draft body.

Source

Thrown at shortcuts/mail/draft/patch.go:799

		if removePart(child, targetPartID) {
			parent.Dirty = true
			return true
		}
	}
	return false
}

// resolveTarget resolves an AttachmentTarget to a concrete part_id.
// Priority: part_id > cid.
func resolveTarget(snapshot *DraftSnapshot, target AttachmentTarget) (string, error) {
	if id := strings.TrimSpace(target.PartID); id != "" {
		return id, nil
	}
	if cid := strings.TrimSpace(target.CID); cid != "" {
		cid = strings.Trim(cid, "<>")
		part := findPartByCID(snapshot.Body, cid)
		if part == nil {
			return "", fmt.Errorf("no part with cid %q found", cid)
		}
		return part.PartID, nil
	}
	return "", fmt.Errorf("target must specify at least one of part_id or cid")
}

func findPartByCID(root *Part, cid string) *Part {
	if root == nil {
		return nil
	}
	if strings.EqualFold(strings.Trim(root.ContentID, "<>"), cid) {
		return root
	}
	for _, child := range root.Children {
		if found := findPartByCID(child, cid); found != nil {
			return found
		}
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Re-read the draft and use a cid that currently exists in the MIME tree (or target by part_id instead)
  2. Strip angle brackets and whitespace and match cid exactly as stored
  3. If the part was removed earlier in the same patch, drop this op
  4. Verify the draft you are patching is the same one the cid came from

Example fix

// before
{"op":"remove_inline","target":{"cid":"stale-cid@old-draft"}}
// after — refresh snapshot first
{"op":"remove_inline","target":{"cid":"image001@current-draft"}}
Defensive patterns

Strategy: validation

Validate before calling

func cidExists(snap *DraftSnapshot, cid string) bool {
	return findPartByCID(snap.Body, strings.Trim(strings.TrimSpace(cid), "<>")) != nil
}

Type guard

func partHasCID(p *Part, cid string) bool {
	return p != nil && strings.Trim(p.ContentID, "<>") == strings.Trim(cid, "<>")
}

Try / catch

if err := applyOp(snap, op); err != nil && strings.Contains(err.Error(), "no part with cid") {
	// refresh snapshot, re-list cids, then rebuild the op
}

Prevention

When it happens

Trigger: Calling an inline patch op (e.g. remove_inline/replace_inline) with target.cid that does not match any part's Content-ID — wrong cid, cid from a different draft, or the inline part was already removed/rewritten in an earlier op.

Common situations: Citing the cid from the original source HTML after the draft's inline parts were regenerated; case/angle-bracket or whitespace mismatches; referencing cid from a previous draft version.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/cf10dde91141e224. Report an issue: GitHub.