From eecd040dc23ac39a0ceabce38b0d593e00e4b157 Mon Sep 17 00:00:00 2001 From: Dmitry Brigadirov Date: Fri, 13 Mar 2026 13:42:01 +0100 Subject: [PATCH] fix: resolve labels field options using "label" key The ClickUp API returns label-type custom field options with a "label" key instead of "name" (which dropdown fields use). This caused all labels field operations to fail with "available: (none)" because the code only checked opt["name"]. Added getOptionName() helper that checks "name" first, falling back to "label". Updated all call sites: resolveLabelOptions, resolveDropdownOption, listOptionNames, formatDropdownValue, and formatLabelsValue. Fixes setting labels fields via --field "SF :: Team=Web" on both task create and task edit, including comma-separated multi-labels. --- pkg/cmd/task/custom_fields.go | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/pkg/cmd/task/custom_fields.go b/pkg/cmd/task/custom_fields.go index 369f8f4..c688266 100644 --- a/pkg/cmd/task/custom_fields.go +++ b/pkg/cmd/task/custom_fields.go @@ -112,7 +112,7 @@ func resolveDropdownOption(field *clickup.CustomField, optionName string) (inter } for _, opt := range options { - if name, ok := opt["name"].(string); ok { + if name := getOptionName(opt); name != "" { if strings.EqualFold(name, optionName) { if id, ok := opt["id"].(string); ok { return id, nil @@ -144,7 +144,7 @@ func resolveLabelOptions(field *clickup.CustomField, rawValue string) (interface } found := false for _, opt := range options { - if optName, ok := opt["name"].(string); ok { + if optName := getOptionName(opt); optName != "" { if strings.EqualFold(optName, name) { if id, ok := opt["id"].(string); ok { ids = append(ids, id) @@ -206,11 +206,23 @@ func extractTypeConfigOptions(typeConfig interface{}) []map[string]interface{} { return result } +// getOptionName returns the display name for a custom field option. +// Dropdown fields use the "name" key, while labels fields use "label". +func getOptionName(opt map[string]interface{}) string { + if name, ok := opt["name"].(string); ok { + return name + } + if label, ok := opt["label"].(string); ok { + return label + } + return "" +} + // listOptionNames returns a comma-separated list of option names. func listOptionNames(options []map[string]interface{}) string { var names []string for _, opt := range options { - if name, ok := opt["name"].(string); ok { + if name := getOptionName(opt); name != "" { names = append(names, name) } } @@ -340,7 +352,7 @@ func formatDropdownValue(field clickup.CustomField) string { options := extractTypeConfigOptions(field.TypeConfig) for _, opt := range options { if id, ok := opt["id"].(string); ok && id == s { - if name, ok := opt["name"].(string); ok { + if name := getOptionName(opt); name != "" { return name } } @@ -354,7 +366,7 @@ func formatDropdownValue(field clickup.CustomField) string { idx := int(optionIdx) for _, opt := range options { if orderIdx, ok := opt["orderindex"].(float64); ok && int(orderIdx) == idx { - if name, ok := opt["name"].(string); ok { + if name := getOptionName(opt); name != "" { return name } } @@ -373,7 +385,7 @@ func formatLabelsValue(field clickup.CustomField) string { optionMap := make(map[string]string) for _, opt := range options { if id, ok := opt["id"].(string); ok { - if name, ok := opt["name"].(string); ok { + if name := getOptionName(opt); name != "" { optionMap[id] = name } } @@ -392,7 +404,7 @@ func formatLabelsValue(field clickup.CustomField) string { idx := int(val) for _, opt := range options { if orderIdx, ok := opt["orderindex"].(float64); ok && int(orderIdx) == idx { - if name, ok := opt["name"].(string); ok { + if name := getOptionName(opt); name != "" { names = append(names, name) } }