{"record":{"id":"01d2e7f78795eb15","repo":"larksuite/cli","slug":"inline-part-q-not-found","errorCode":null,"errorMessage":"inline part %q not found","messagePattern":"inline part %q not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":674,"sourceCode":"\t\tcontainer, err = ensureInlineContainerRef(containerRef)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"inline image %q: %w\", path, err)\n\t\t}\n\t}\n\tcontainer.Children = append(container.Children, inline)\n\tcontainer.Dirty = true\n\treturn container, nil\n}\n\nfunc addInline(dctx *DraftCtx, snapshot *DraftSnapshot, path, cid, fileName, contentType string) error {\n\t_, err := loadAndAttachInline(dctx, snapshot, path, cid, fileName, nil)\n\treturn err\n}\n\nfunc replaceInline(dctx *DraftCtx, snapshot *DraftSnapshot, partID, path, cid, fileName, contentType string) error {\n\tpart := findPart(snapshot.Body, partID)\n\tif part == nil {\n\t\treturn fmt.Errorf(\"inline part %q not found\", partID)\n\t}\n\tif !isInlinePart(part) {\n\t\treturn fmt.Errorf(\"part %q is not an inline MIME part\", partID)\n\t}\n\tinfo, err := dctx.FIO.Stat(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := checkSnapshotAttachmentLimit(snapshot, info.Size(), part); err != nil {\n\t\treturn err\n\t}\n\tf, err := dctx.FIO.Open(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\tcontent, err := io.ReadAll(f)\n\tif err != nil {","sourceCodeStart":656,"sourceCodeEnd":692,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L656-L692","documentation":"replaceInline throws this when no MIME part with the given partID exists in the draft snapshot body tree. findPart walks the whole MIME tree and returns nil for unknown IDs, so the replacement target cannot be located.","triggerScenarios":"applyOp -> replaceInline with a partID that does not exist in the current snapshot: typo, part already removed, or partID taken from a different/stale draft snapshot.","commonSituations":"Script caches part IDs from an earlier fetch then re-patches after the draft changed; copying a partID from a sibling draft; case/whitespace mistakes in the ID.","solutions":["Re-fetch the draft to get the current part list and use a fresh partID","Check the partID for typos or trailing whitespace","Confirm the part still exists (a prior remove operation may have deleted it)","Verify you are patching the same draft the partID came from"],"exampleFix":"// before\n--replace-inline part_id=old_id_123 --path ./new.png\n// after\nlark mail draft get --draft-id D   # look up current inline part IDs\n--replace-inline part_id=current_id --path ./new.png","handlingStrategy":"validation","validationCode":"snap, _ := draftGet(draftID)\nids := collectPartIDs(snap.Body)\nif !slices.Contains(ids, partID) {\n    return fmt.Errorf(\"part %s not in draft; have %v\", partID, ids)\n}","typeGuard":"func partExists(snap *DraftSnapshot, id string) bool {\n    return snap != nil && snap.Body != nil && findPart(snap.Body, id) != nil\n}","tryCatchPattern":"if err := replaceInline(...); err != nil {\n    if strings.Contains(err.Error(), \"not found\") {\n        // refetch draft and refresh partID\n    }\n}","preventionTips":["Re-fetch the draft immediately before each patch","Never cache part IDs across draft mutations","Copy partIDs programmatically, not by hand","Verify the draft ID matches the one IDs came from"],"tags":["mail","draft","mime-part","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"}