temporalio/temporal · error · converter.ErrUnableToDecode
%w: invalid item value type in KeywordList value (got: %T, e
Error message
%w: invalid item value type in KeywordList value (got: %T, expected: string)
What it means
DecodeKeywordList wraps converter.ErrUnableToDecode when an element of the decoded value is not a Go string. After the payload converter produces []any, each item must be a string for a KEYWORD_LIST; any other item type (number, bool, nested list) aborts with the offending value's dynamic type reported. Note the message prints the whole dv value's type, not the item's, which can be slightly misleading.
Source
Thrown at common/searchattribute/sadefs/encode_value.go:160
if err != nil {
return nil, err
}
if dv == nil {
return nil, nil
}
// Validate that every value is a string.
tdv, ok := dv.([]any)
if !ok {
//nolint:forbidigo // this should never happen
panic(fmt.Sprintf("unexpected return type of decodeValueTyped (got: %T, expected: []any)", dv))
}
res := make([]string, len(tdv))
for i, v := range tdv {
switch vt := v.(type) {
case string:
res[i] = vt
default:
return nil, fmt.Errorf(
"%w: invalid item value type in KeywordList value (got: %T, expected: string)",
converter.ErrUnableToDecode,
dv,
)
}
}
return res, nil
}
View on GitHub (pinned to bde624efd1)
Solutions
- Ensure the encoder writes only string items into KeywordList values (use sadefs.EncodeValue with []string).
- Coerce/convert numeric or bool items to strings at the producer before encoding.
- Inspect the payload items (the offending value is named in the error) and fix the writer.
Example fix
// before
items := []any{"a", 42}
payload, _ := converter.DefaultDataConverter.ToPayload(items)
// after
payload, _ := sadefs.EncodeValue([]string{"a", "42"}, false) Defensive patterns
Strategy: type-guard
Validate before calling
for _, v := range items {
if _, ok := v.(string); !ok {
return fmt.Errorf("keyword list contains non-string item")
}
} Type guard
func isStringList(items []any) bool {
for _, v := range items {
if _, ok := v.(string); !ok {
return false
}
}
return true
} Try / catch
if errors.Is(err, converter.ErrUnableToDecode) { /* inspect payload items and fix producer */ } Prevention
- Encode keyword lists only from []string via sadefs.EncodeValue
- Reject heterogeneous lists at the producer
- Avoid hand-building payloads with generic converters for KEYWORD_LIST
When it happens
Trigger: Calling DecodeKeywordList (or Validate) on a payload whose list contains non-string items — e.g. a mixed-type list encoded via a generic JSON converter or hand-built temporal/api common Payload.
Common situations: Values built by external tools writing raw payloads; data migrated from another system where the field held heterogeneous types; SDK versions encoding nil/non-string items.
Related errors
- %w: %T (expected string)
- %w: %T (expected string)
- unexpected return type of decodeValueTyped (got: %T, expecte
- unsupported type for VisibilitySearchAttributes: %T
- %w: %s
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/8b4d91a1658a56b4.
Report an issue: GitHub.