{"record":{"id":"040e11f336e016ee","repo":"temporalio/temporal","slug":"w-list-of-values-not-allowed-for-type-t","errorCode":null,"errorMessage":"%w: list of values not allowed for type %T","messagePattern":"%w: list of values not allowed for type %T","errorType":"exception","errorClass":"converter.ErrUnableToDecode","httpStatus":null,"severity":"error","filePath":"common/searchattribute/sadefs/encode_value.go","lineNumber":130,"sourceCode":"\t\tif val == nil {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn *val, nil\n\t}\n\tvar listVal []T\n\tif err := payload.Decode(value, &listVal); err != nil {\n\t\treturn nil, err\n\t}\n\tif len(listVal) == 0 {\n\t\treturn nil, nil\n\t}\n\tif allowList {\n\t\treturn listVal, nil\n\t}\n\tif len(listVal) == 1 {\n\t\treturn listVal[0], nil\n\t}\n\treturn nil, fmt.Errorf(\n\t\t\"%w: list of values not allowed for type %T\",\n\t\tconverter.ErrUnableToDecode,\n\t\tlistVal[0],\n\t)\n}\n\nfunc DecodeKeywordList(value *commonpb.Payload) ([]string, error) {\n\t// Decode to []any because json.Unmarshal decodes null values to zero value,\n\t// i.e., if we decoded to []string, null values would become empty string,\n\t// which is invalid.\n\tdv, err := decodeValueTyped[[]any](value, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif dv == nil {\n\t\treturn nil, nil\n\t}\n\t// Validate that every value is a string.","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/searchattribute/sadefs/encode_value.go#L112-L148","documentation":"decodeValueTyped returns converter.ErrUnableToDecode wrapped with \"list of values not allowed\" when a payload decodes to a multi-element list but allowList is false and the list has more than one element. Single-element lists are unwrapped to the scalar; longer lists are rejected because the declared type is scalar. KeywordList decoding always passes allowList=false but uses its own path (DecodeKeywordList).","triggerScenarios":"DecodeValue with a scalar type (e.g. Keyword or Bool) whose payload converter yields a []any with 2+ elements — i.e. the value was written as a list but is being read as a scalar.","commonSituations":"Type of a search attribute changed from a list-ish/multi-value to scalar (or vice versa) between write and read; Elasticsearch multi-valued fields decoded without allowList=true.","solutions":["Pass allowList=true to DecodeValue if the underlying field is genuinely multi-valued.","Align the declared INDEXED_VALUE_TYPE with how the value was encoded (list vs scalar).","Pre-check with DecodeKeywordList or the converter when the field may contain multiple values."],"exampleFix":"// before\nval, err := sadefs.DecodeValue(payload, enumspb.INDEXED_VALUE_TYPE_KEYWORD, false)\n// after\nval, err := sadefs.DecodeValue(payload, enumspb.INDEXED_VALUE_TYPE_KEYWORD, true) // multi-valued field","handlingStrategy":"validation","validationCode":"if len(values) > 1 && !allowList {\n    return fmt.Errorf(\"field is multi-valued; pass allowList=true\")\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, converter.ErrUnableToDecode) { /* retry with allowList=true */ }","preventionTips":["Match allowList to the field's actual cardinality in the visibility store","Keep the attribute's declared type stable across write and read paths","Prefer DecodeKeywordList for known multi-valued keyword fields"],"tags":["go","search-attributes","decode","list-vs-scalar"],"backgroundTag":"unable-to-decode-payload","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}