larksuite/cli · error
custom JSON type %s requires an explicit Shape
Error message
custom JSON type %s requires an explicit Shape
What it means
Struct fields whose types implement custom JSON encoding (json.Marshaler or encoding.TextMarshaler, e.g. time.Time, json.Number-style wrappers, big.Int) are rejected: the compiler cannot infer the wire schema from a MarshalJSON method, since arbitrary bytes could be emitted. An explicit Shape or a plain struct is required.
Source
Thrown at shortcuts/common/typed_compile_data.go:154
case reflect.Slice, reflect.Array:
if baseType == jsonRawMessageType {
return nil, fmt.Errorf("json.RawMessage requires an explicit Shape")
}
if baseType.Elem().Kind() == reflect.Uint8 {
return nil, fmt.Errorf("byte slice or array %s requires an explicit Shape", baseType)
}
if len(schema.enum) > 0 || hasStringConstraints(schema) || hasNumberConstraints(schema) || schema.format != "" {
return nil, fmt.Errorf("array field has incompatible schema constraint")
}
elementSchema := schemaTag{required: true}
elementShape, err := shapeForType(baseType.Elem(), elementSchema, input, active)
if err != nil {
return nil, fmt.Errorf("array item: %w", err)
}
shape = typedArrayShape{Items: elementShape, MinItems: schema.minItems, MaxItems: schema.maxItems}
case reflect.Struct:
if implementsCustomEncoding(baseType) {
return nil, fmt.Errorf("custom JSON type %s requires an explicit Shape", baseType)
}
if len(schema.enum) > 0 || hasStringConstraints(schema) || hasNumberConstraints(schema) || hasItemConstraints(schema) || schema.format != "" {
return nil, fmt.Errorf("object field has incompatible schema constraint")
}
object, err := compileStructShape(baseType, input, baseType.String(), active)
if err != nil {
return nil, err
}
shape = object
case reflect.Map:
return nil, fmt.Errorf("map type %s requires an explicit Shape", baseType)
case reflect.Interface:
return nil, fmt.Errorf("interface type %s requires an explicit Shape", baseType)
default:
return nil, fmt.Errorf("Go type %s cannot be mapped to a ValueShape", t)
}
if schema.nullable != nil && *schema.nullable {
shape = typedOneOfShape{Variants: []typedValueShape{shape, typedNullShape{}}}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Replace the field with the encoded representation, e.g. use `string` for a time.Time (RFC 3339) and format the value before assigning.
- Provide an explicit Output.Data.Shape that declares the field as a string/number shape matching the encoding.
- If the type is structurally simple, remove the MarshalJSON/UnmarshalJSON methods (or use a plain alias struct) so the compiler can walk it.
Example fix
// before
type Data struct {
CreatedAt time.Time `json:"created_at"`
}
// after
type Data struct {
CreatedAt string `json:"created_at"` // t.Format(time.RFC3339)
} Defensive patterns
Strategy: validation
Validate before calling
func implementsCustomEncoding(t reflect.Type) bool {
for t.Kind() == reflect.Pointer { t = t.Elem() }
return reflect.PointerTo(t).Implements(reflect.TypeFor[json.Marshaler]()) ||
reflect.PointerTo(t).Implements(reflect.TypeFor[encoding.TextMarshaler]())
}
// reject any Data struct field whose type satisfies implementsCustomEncoding Type guard
func isCustomJSONType(t reflect.Type) bool {
return reflect.PointerTo(t).Implements(reflect.TypeFor[json.Marshaler]())
} Prevention
- Store timestamps as RFC 3339 strings, not time.Time, in wire Data structs.
- Keep MarshalJSON-bearing domain types out of typed Data; convert to plain fields first.
- Check new field types with implementsCustomEncoding before adding them to Data.
When it happens
Trigger: A Data struct field whose type implements json.Marshaler or encoding.TextMarshaler (time.Time, url.URL, big.Int, custom ID types) hits shapeForType's reflect.Struct case during registration.
Common situations: Using time.Time directly for date fields; domain types with custom MarshalJSON reused as Data fields; generated types that embed custom encoders.
Related errors
- json.RawMessage requires an explicit Shape
- byte slice or array %s requires an explicit Shape
- map type %s requires an explicit Shape
- interface type %s requires an explicit Shape
- Go type %s cannot be mapped to a ValueShape
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/650c915815614bb1.
Report an issue: GitHub.