apache/beam · error
couldn't decode characteristic for variant
Error message
couldn't decode characteristic for variant %v handler %v: %v
What it means
When reading a characteristic value for a runner variant+handler, config.go decodes the YAML node into the characteristic's Go type via reflection. The decode is expected to succeed because the config was pre-validated, so failure triggers a panic indicating the validated config and the decode path have diverged (an internal invariant break).
Solutions
- Check the variant/handler YAML content against the expected characteristic schema
- Regenerate or simplify the config file to the documented format
- Verify the handler key exists with a compatible value type (string vs struct, etc.)
- File a bug with the config file if pre-validation passes but decode fails
Example fix
// before: mismatched yaml value type variant: handler: 123 // after variant: handler: "valid-string-value"
Defensive patterns
Strategy: validation
Validate before calling
// validate config against the schema before load
if err := config.Validate(yamlBytes); err != nil { return fmt.Errorf("invalid characteristic config: %w", err) } Try / catch
// GetCharacteristics panics by design; guard the loader
defer func() { if r := recover(); r != nil { err = fmt.Errorf("characteristic decode failed: %v", r) } }() Prevention
- Only load config files matching the documented schema
- Run the config through the validator CLI/loader before use
- Avoid hand-generating yaml.Node structures programmatically
When it happens
Trigger: GetCharacteristics is called with a handler key present in the variant's handlers map, but yn.Decode fails — e.g. the yaml.Node's shape doesn't match the characteristic's Go type, or KnownFields(true)-style strictness rejects content the pre-validation passed.
Common situations: Hand-edited or programmatically generated config YAML whose node structure mismatches the ConfigCharacteristic type; running a custom variant config; a bug where validation and decode use different type mappings.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- error re-encoding characteristic for variant
- error decoding append bag user state window key
- error decoding residual header:
- error decoding watermarks
- generating bundle for stage
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/69e57dec6539ffe7.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/runners/prism/internal/config/config.go:142
func (v *Variant) GetCharacteristics(handler string) any {
if v == nil {
return nil
}
md, ok := v.parent.metadata[handler]
if !ok {
return nil
}
rt := md.ConfigCharacteristic()
// Get a pointer to the concrete value.
rtv := reflect.New(rt)
// look up the handler urn in the variant.
yn := v.handlers[handler]
//
if err := yn.Decode(rtv.Interface()); err != nil {
// We prevalidated the config, so this shouldn't happen.
panic(fmt.Sprintf("couldn't decode characteristic for variant %v handler %v: %v", v.name, handler, err))
}
// Return the value pointed to by the pointer.
return rtv.Elem().Interface()
}
// HandlerRegistry stores known handlers and their associated metadata needed to parse
// the YAML configuration.
type HandlerRegistry struct {
variations map[string]*rawVariant
metadata map[string]HandlerMetadata
// cached names
variantIDs, handerIDs []string
}
// NewHandlerRegistry creates an initialized HandlerRegistry.
func NewHandlerRegistry() *HandlerRegistry {View on GitHub (pinned to 12126d8942)