temporalio/temporal · error · sadefs.ErrInvalidType
%w: %v
Error message
%w: %v
What it means
parseValueTyped converts a plain string (from Stringify/Parse of a search attribute) back into a typed value. Its switch handles Bool, Datetime, and UNSPECIFIED; any other declared type (Keyword, Text, KeywordList, Int, etc.) hits the default branch and returns sadefs.ErrInvalidType, because those types are not parseable from a bare string by this single-value parser.
Source
Thrown at common/searchattribute/stringify.go:146
var err error
switch t {
case enumspb.INDEXED_VALUE_TYPE_TEXT,
enumspb.INDEXED_VALUE_TYPE_KEYWORD,
enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST:
val = valStr
case enumspb.INDEXED_VALUE_TYPE_INT:
val, err = strconv.ParseInt(valStr, 10, 64)
case enumspb.INDEXED_VALUE_TYPE_DOUBLE:
val, err = strconv.ParseFloat(valStr, 64)
case enumspb.INDEXED_VALUE_TYPE_BOOL:
val, err = strconv.ParseBool(valStr)
case enumspb.INDEXED_VALUE_TYPE_DATETIME:
val, err = time.Parse(time.RFC3339Nano, valStr)
case enumspb.INDEXED_VALUE_TYPE_UNSPECIFIED:
val = parseValueUnspecified(valStr)
default:
err = fmt.Errorf("%w: %v", sadefs.ErrInvalidType, t)
}
return val, err
}
func parseValueUnspecified(valStr string) any {
var val any
var err error
if val, err = strconv.ParseInt(valStr, 10, 64); err == nil {
} else if val, err = strconv.ParseBool(valStr); err == nil {
} else if val, err = strconv.ParseFloat(valStr, 64); err == nil {
} else if val, err = time.Parse(time.RFC3339Nano, valStr); err == nil {
} else if isJSONArray(valStr) {
arr, err := parseJSONArray(valStr, enumspb.INDEXED_VALUE_TYPE_UNSPECIFIED)
if err != nil {
val = valStr
} else {View on GitHub (pinned to bde624efd1)
Solutions
- Only run parseValueTyped for Bool/Datetime/Unspecified types; use the appropriate string/JSON path for Keyword/Text.
- Route list types (KeywordList) through parseValueOrArray so parseJSONArray handles them.
- Verify the type map returns the expected type for the attribute name before parsing.
Example fix
// before val, err := parseValueTyped(enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, "[\"a\"]") // invalid // after val, err := parseJSONArray(enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, "[\"a\"]")
Defensive patterns
Strategy: type-guard
Validate before calling
switch t {
case enumspb.INDEXED_VALUE_TYPE_BOOL, enumspb.INDEXED_VALUE_TYPE_DATETIME,
enumspb.INDEXED_VALUE_TYPE_UNSPECIFIED:
default:
return fmt.Errorf("type %v not parseable as scalar", t)
} Type guard
func scalarParseable(t enumspb.IndexedValueType) bool {
return t == enumspb.INDEXED_VALUE_TYPE_BOOL ||
t == enumspb.INDEXED_VALUE_TYPE_DATETIME ||
t == enumspb.INDEXED_VALUE_TYPE_UNSPECIFIED
} Try / catch
if errors.Is(err, sadefs.ErrInvalidType) { /* route to parseJSONArray or string path */ } Prevention
- Resolve the attribute type first and choose the matching parse path
- Send Keyword/Text values through string handling, not parseValueTyped
- Test Parse/Stringify round-trips for each attribute type
When it happens
Trigger: Calling Stringify/Parse (via parseValueOrArray -> parseValueTyped) on a search attribute whose declared type is not Bool/Datetime — e.g. parsing "MyKeyword=abc" where the type maps to KEYWORD through the scalar path instead of the array/string path.
Common situations: Using searchattribute.Parse on user-supplied key=value strings where the attribute type resolution yields an unparseable type; feeding KeywordList-typed attributes into the scalar parser instead of parseJSONArray.
Related errors
- %w: %v
- %w: %s
- %w: %s
- %w: list of values not allowed for type %T
- %w: invalid item value type in KeywordList value (got: %T, e
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/aaf795b75d36cecb.
Report an issue: GitHub.