hashicorp/nomad · error
cannot serialize %s
Error message
cannot serialize %s
What it means
interfaceFromCtyValue ends with a default branch for cty types it does not know how to convert to plain Go values (non-primitive, non-collection, non-object/tuple, non-capsule-extractable). The comment says it should never happen; hitting it means the type/conformance contract between decodeInterface and the value was violated or a new cty kind appeared.
Source
Thrown at jobspec2/parse_map.go:175
case t.IsObjectType():
result := map[string]any{}
for k := range t.AttributeTypes() {
av := val.GetAttr(k)
avv, err := interfaceFromCtyValue(av)
if err != nil {
return nil, err
}
result[k] = avv
}
return result, nil
case t.IsCapsuleType():
rawVal := val.EncapsulatedValue()
return rawVal, nil
default:
// should never happen
return nil, fmt.Errorf("cannot serialize %s", t.FriendlyName())
}
}
func isCollectionOfMaps(t cty.Type) bool {
switch {
case t.IsCollectionType():
et := t.ElementType()
return et.IsMapType() || et.IsObjectType()
case t.IsTupleType():
ets := t.TupleElementTypes()
for _, et := range ets {
if !et.IsMapType() && !et.IsObjectType() {
return false
}
}
return len(ets) > 0
default:View on GitHub (pinned to 482b49bf1a)
Solutions
- Report/inspect the type name in the message; confirm the jobspec value's declared type matches the supplied value.
- Upgrade (or pin) the hashicorp/hcl2/cty dependency so type kinds and conversion code agree.
- Simplify the jobspec construct producing the exotic type (avoid unusual nested/type expressions).
- If reproducible, file a bug — this code path is documented as unreachable under correct preconditions.
Example fix
// before
// val declared as cty.DynamicPseudoType but carries unhandled kind
// after
// declare explicit concrete types in the jobspec
variable "port" { type = number } Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-check convertibility
typeName := t.FriendlyName()
switch {
case t.IsPrimitiveType(), t.IsCollectionType(), t.IsObjectType(), t.IsTupleType(), t.IsCapsuleType():
// handled
default:
return fmt.Errorf("unsupported cty type for decoding: %s", typeName)
} Type guard
func isSupportedCtyType(t cty.Type) bool {
return t.IsPrimitiveType() || t.IsCollectionType() ||
t.IsObjectType() || t.IsTupleType() || t.IsCapsuleType()
} Try / catch
v, err := interfaceFromCtyValue(val, t)
if err != nil && strings.HasPrefix(err.Error(), "cannot serialize ") {
// capture type name, check dependency versions, report bug
} Prevention
- Keep hashicorp/hcl2 and cty versions aligned with the library's expectations.
- Declare explicit concrete types in jobspec variables.
- Treat this error as a bug signal: report with the type name from the message.
When it happens
Trigger: decodeInterface invoked with a cty.Type that matches none of the handled switch cases and whose IsCapsuleType branch does not apply, causing 'cannot serialize <FriendlyName>'.
Common situations: Bug in the library or an upgraded cty version introducing a type kind jobspec2 does not handle; decoding a value whose declared type does not match its runtime conformance (violated precondition); exotic capsule types from extensions.
Related errors
- value is not known
- <combined HCL diagnostics from str.String()>
- value is not known
- expected map/object cty value, got %s
- cannot serialize %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/2ae177227ad3a64d.
Report an issue: GitHub.