{"record":{"id":"f1f831c3b266a64e","repo":"larksuite/cli","slug":"recipient-field-must-be-one-of-to-cc-bcc-f1f831","errorCode":null,"errorMessage":"recipient field must be one of to/cc/bcc","messagePattern":"recipient field must be one of to/cc/bcc","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":160,"sourceCode":"\tcase \"remove_calendar\":\n\t\treturn applyCalendarRemove(snapshot)\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported patch op %q\", op.Op)\n\t}\n\treturn nil\n}\n\nfunc ensureHeaderEditable(name string, options PatchOptions) error {\n\tif protectedHeaders[strings.ToLower(strings.TrimSpace(name))] && !options.AllowProtectedHeaderEdits {\n\t\treturn fmt.Errorf(\"header %q is protected; rerun with allow_protected_header_edits\", name)\n\t}\n\treturn nil\n}\n\nfunc setRecipients(snapshot *DraftSnapshot, field string, addrs []Address) error {\n\tfield = strings.ToLower(strings.TrimSpace(field))\n\tif !isRecipientField(field) {\n\t\treturn fmt.Errorf(\"recipient field must be one of to/cc/bcc\")\n\t}\n\tnormalized := make([]Address, 0, len(addrs))\n\tseen := map[string]bool{}\n\tfor _, addr := range addrs {\n\t\tif strings.TrimSpace(addr.Address) == \"\" {\n\t\t\treturn fmt.Errorf(\"recipient address is empty\")\n\t\t}\n\t\tkey := strings.ToLower(strings.TrimSpace(addr.Address))\n\t\tif seen[key] {\n\t\t\tcontinue\n\t\t}\n\t\tseen[key] = true\n\t\tnormalized = append(normalized, Address{\n\t\t\tName:    addr.Name,\n\t\t\tAddress: strings.TrimSpace(addr.Address),\n\t\t})\n\t}\n\t_, headerName := recipientField(snapshot, field)","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L142-L178","documentation":"setRecipients validates the recipient field name via isRecipientField; only 'to', 'cc', and 'bcc' (case-insensitive) are accepted. Any other field string is rejected, and the same validation is also applied by buildDraftEditPatch.","triggerScenarios":"Calling Apply with PatchOp{Op:\"set_recipients\"} where Field is e.g. \"To:\" (with colon), \"recipient\", \"from\", or an empty string.","commonSituations":"Passing display labels ('To:') instead of the bare field name; using 'from' or 'reply-to' which this op does not support; field values deserialized with surrounding whitespace/casing issues.","solutions":["Use exactly \"to\", \"cc\", or \"bcc\" (case-insensitive; trim whitespace, drop any colon).","If you need to change From/Reply-To, use the dedicated ops or header machinery instead of set_recipients.","Normalize the field in your caller: strings.ToLower(strings.TrimSpace(strings.TrimSuffix(field, \":\")))."],"exampleFix":"// before\nop := PatchOp{Op: \"set_recipients\", Field: \"To:\", Addresses: addrs}\n// after\nop := PatchOp{Op: \"set_recipients\", Field: \"to\", Addresses: addrs}","handlingStrategy":"validation","validationCode":"var recipientFields = map[string]bool{\"to\": true, \"cc\": true, \"bcc\": true}\nfunc isRecipientField(f string) bool {\n    f = strings.ToLower(strings.TrimSpace(strings.TrimSuffix(strings.TrimSpace(f), \":\")))\n    return recipientFields[f]\n}","typeGuard":"func normalizeRecipientField(f string) (string, bool) {\n    f = strings.ToLower(strings.TrimSpace(strings.TrimSuffix(strings.TrimSpace(f), \":\")))\n    return f, recipientFields[f]\n}","tryCatchPattern":"if err := Apply(ctx, dctx, ops, opts); err != nil {\n    if strings.Contains(err.Error(), \"one of to/cc/bcc\") {\n        return fmt.Errorf(\"use bare field name 'to'|'cc'|'bcc': %w\", err)\n    }\n    return err\n}","preventionTips":["Use constants (\"to\", \"cc\", \"bcc\") instead of user-facing labels.","Strip colons and whitespace from field values before patching.","Route From/Reply-To changes to dedicated ops, not set_recipients.","Add a table test covering accepted and rejected field names."],"tags":["email","draft-patch","validation"],"backgroundTag":"invalid-field-name","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"}