{"record":{"id":"68140da1a520cf63","repo":"larksuite/cli","slug":"body-container-is-nil","errorCode":null,"errorMessage":"body container is nil","messagePattern":"body container is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":464,"sourceCode":"\tif strings.EqualFold(part.MediaType, \"multipart/mixed\") {\n\t\tfor idx := range part.Children {\n\t\t\tchild := part.Children[idx]\n\t\t\tif child == nil || strings.EqualFold(child.ContentDisposition, \"attachment\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn &part.Children[idx]\n\t\t}\n\t\tif len(part.Children) == 0 {\n\t\t\tpart.Children = append(part.Children, nil)\n\t\t\treturn &part.Children[0]\n\t\t}\n\t}\n\treturn root\n}\n\nfunc ensureBodyPartRef(partRef **Part, bodyKind string) (*Part, error) {\n\tif partRef == nil {\n\t\treturn nil, fmt.Errorf(\"body container is nil\")\n\t}\n\tif *partRef == nil {\n\t\tleaf := newBodyLeaf(bodyKind)\n\t\tleaf.Dirty = true\n\t\t*partRef = leaf\n\t\treturn leaf, nil\n\t}\n\tpart := *partRef\n\tif !part.IsMultipart() {\n\t\tif strings.EqualFold(part.MediaType, bodyKind) {\n\t\t\treturn part, nil\n\t\t}\n\t\tif !isBodyKind(part.MediaType) {\n\t\t\treturn nil, fmt.Errorf(\"cannot rewrite non-body media type %q\", part.MediaType)\n\t\t}\n\t\tnewLeaf := newBodyLeaf(bodyKind)\n\t\talt := newMultipartContainer(\"multipart/alternative\")\n\t\tif strings.EqualFold(part.MediaType, \"text/plain\") {","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L446-L482","documentation":"ensureBodyPartRef was handed a nil **Part pointer, meaning there is no addressable slot in the MIME tree in which to create or find the body part. Unlike a nil *Part (an empty slot that gets filled with a new leaf), a nil **Part reference is a programming/state error in the caller. Only reached when the caller passes a literally nil pointer rather than the address of a (possibly nil) slot.","triggerScenarios":"Calling ensureBodyPartRef(nil, bodyKind) directly, or recursively via the multipart/related branch when a child slot yields a nil reference; also reachable through ensureBodyPart if primaryBodyRootRef returned a nil root pointer under unusual tree states.","commonSituations":"Custom callers of the internal body-ensure helpers passing an unaddressable/nil reference; MIME trees corrupted by earlier mutations that left dangling child slots; reflection-based or generic tree code constructing bad references.","solutions":["Pass a valid &snapshot.Body (or the address of an actual child slot) instead of a nil pointer.","Guard callers so they only invoke ensureBodyPartRef with references obtained from primaryBodyRootRef or a real Children[idx] slot.","Repair/rebuild the snapshot tree if earlier mutations left nil or dangling child references."],"exampleFix":"// before\npart, err := ensureBodyPartRef(nil, \"text/html\")\n// after\npartRef := primaryBodyRootRef(&snapshot.Body)\npart, err := ensureBodyPartRef(partRef, \"text/html\")","handlingStrategy":"type-guard","validationCode":"if partRef == nil { partRef = primaryBodyRootRef(&snapshot.Body) }\npart, err := ensureBodyPartRef(partRef, \"text/html\")","typeGuard":"func validPartRef(r **Part) bool { return r != nil }","tryCatchPattern":null,"preventionTips":["Only pass references from primaryBodyRootRef or real Children slots into ensureBodyPartRef.","Never pass a literal nil **Part; pass &snapshot.Body instead.","Validate tree integrity after custom MIME mutations."],"tags":["email","mime","draft","nil-pointer"],"backgroundTag":"nil-pointer-container","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"}