{"record":{"id":"f53164cd18440ee7","repo":"larksuite/cli","slug":"set-header-requires-name","errorCode":null,"errorMessage":"set_header requires name","messagePattern":"set_header requires name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/model.go","lineNumber":302,"sourceCode":"\t\tif strings.TrimSpace(op.Address) == \"\" {\n\t\t\treturn fmt.Errorf(\"%s requires address\", op.Op)\n\t\t}\n\tcase \"set_reply_to\":\n\t\tif len(op.Addresses) == 0 {\n\t\t\treturn fmt.Errorf(\"set_reply_to requires addresses\")\n\t\t}\n\tcase \"clear_reply_to\":\n\tcase \"set_body\", \"set_reply_body\":\n\tcase \"replace_body\", \"append_body\":\n\t\tif !isBodyKind(op.BodyKind) {\n\t\t\treturn fmt.Errorf(\"body_kind must be text/plain or text/html\")\n\t\t}\n\t\tif op.Selector != \"\" && op.Selector != \"primary\" {\n\t\t\treturn fmt.Errorf(\"selector must be primary\")\n\t\t}\n\tcase \"set_header\":\n\t\tif strings.TrimSpace(op.Name) == \"\" {\n\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\")","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/model.go#L284-L320","documentation":"Thrown by PatchOp.Validate() in shortcuts/mail/draft/model.go:302 when a set_header op has an empty or whitespace-only Name. The header name identifies which custom header to set on the mail, so it is mandatory. Value may be empty; name may not.","triggerScenarios":"{\"op\":\"set_header\",\"value\":\"x\"} with no name key; name:\"\" or name:\"  \"; a variable feeding Name that was never assigned; JSON with omitempty dropping an empty name.","commonSituations":"Dynamic header construction from key/value maps where the key is missing; iterating over pairs and emitting an op for a blank key; template placeholders left unsubstituted.","solutions":["Provide the header name in op.Name, e.g. {\"op\":\"set_header\",\"name\":\"X-Custom-Id\",\"value\":\"123\"}.","Skip pairs with empty keys when building ops from a map.","Trim and check the key before emitting the op."],"exampleFix":"// before\nfor k, v := range headers {\n    ops = append(ops, PatchOp{Op: \"set_header\", Value: v}) // name forgotten\n}\n\n// after\nfor k, v := range headers {\n    if strings.TrimSpace(k) == \"\" { continue }\n    ops = append(ops, PatchOp{Op: \"set_header\", Name: k, Value: v})\n}","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(op.Name) == \"\" {\n    return fmt.Errorf(\"set_header needs a name\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Skip map entries with blank keys when generating set_header ops.","Trim keys from user/config input before use.","Build headers through a SetHeader(name, value) helper that validates both fields."],"tags":["mail","validation","patch-op","headers"],"backgroundTag":"empty-required-field","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"}