temporalio/temporal · error · sadefs.ErrInvalidString
%w: %s
Error message
%w: %s
What it means
validateStrings wraps sadefs.ErrInvalidString when a decoded string search attribute value contains invalid UTF-8. The visibility store (Elasticsearch/SQL) cannot safely index or compare non-UTF-8 bytes, so decoding rejects them early with the offending value in the message.
Source
Thrown at common/searchattribute/sadefs/encode_value.go:81
case enumspb.INDEXED_VALUE_TYPE_TEXT:
return validateStrings(decodeValueTyped[string](value, allowList))
case enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST:
return validateStrings(decodeValueTyped[[]string](value, false))
default:
return nil, fmt.Errorf("%w: %v", ErrInvalidType, t)
}
}
func validateStrings(anyValue any, err error) (any, error) {
if err != nil {
return anyValue, err
}
// validate strings
switch value := anyValue.(type) {
case string:
if !utf8.ValidString(value) {
return nil, fmt.Errorf("%w: %s", ErrInvalidString, value)
}
case []string:
for _, item := range value {
if !utf8.ValidString(item) {
return nil, fmt.Errorf("%w: %s", ErrInvalidString, item)
}
}
}
return anyValue, err
}
// decodeValueTyped tries to decode to the given type.
// If the input is a list and allowList is false, then it will return only the first element.
// If the input is a list and allowList is true, then it will return the decoded list.
//
//nolint:revive // allowList is a control flag
func decodeValueTyped[T any](value *commonpb.Payload, allowList bool) (any, error) {
// At first, it tries to decode to pointer of actual type (i.e. `*string` for `string`).View on GitHub (pinned to bde624efd1)
Solutions
- Ensure the producer encodes strings as UTF-8 before attaching them as search attributes.
- Sanitize or transcode the offending value (the invalid string is included in the error message) at the workflow-start/memo layer.
- Use utf8.ValidString to pre-validate values before calling EncodeValue/DecodeValue.
Example fix
// before
payload, err := sadefs.EncodeValue(rawBytesAsString, false)
// after
if !utf8.ValidString(s) {
s = strings.ToValidUTF8(s, "\uFFFD")
}
payload, err := sadefs.EncodeValue(s, false) Defensive patterns
Strategy: validation
Validate before calling
if !utf8.ValidString(s) {
return fmt.Errorf("search attribute value is not valid UTF-8")
} Try / catch
if errors.Is(err, sadefs.ErrInvalidString) { /* sanitize and re-encode */ } Prevention
- Run utf8.ValidString on all external strings before attaching as attributes
- Transcode non-UTF-8 input with strings.ToValidUTF8
- Never put raw binary data into Keyword/Text attributes
When it happens
Trigger: DecodeValue on a Keyword, Text, or single-string payload whose bytes do not form valid UTF-8 — typically a payload written by a client that did not validate its string input.
Common situations: Binary data accidentally placed into a Keyword attribute; strings built from raw network bytes or wrong charset encodings (e.g. Latin-1) before being attached to a workflow.
Related errors
- %w: %s
- %w: %v
- %w: list of values not allowed for type %T
- %w: invalid item value type in KeywordList value (got: %T, e
- %w: %v
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/c3bb5bd8cedbaf28.
Report an issue: GitHub.