larksuite/cli · error

%s const is not JSON-encodable: %w

Error message

%s const is not JSON-encodable: %w

What it means

validateShape rejects a typedConstShape whose Value cannot be marshaled with encoding/json. Const values are emitted verbatim into the generated schema, so they must be JSON-encodable; the wrapped json.Marshal error and the shape path are included in the message.

Source

Thrown at shortcuts/common/typed_compile_data.go:286

		}
	case typedBooleanShape:
	case typedIntegerShape:
		if value.Minimum != nil && value.Maximum != nil && *value.Minimum > *value.Maximum {
			return fmt.Errorf("%s minimum exceeds maximum", path)
		}
	case typedNumberShape:
		for _, number := range append(append([]float64{}, value.Enum...), pointerFloats(value.Minimum, value.Maximum)...) {
			if math.IsNaN(number) || math.IsInf(number, 0) {
				return fmt.Errorf("%s number constraints must be finite", path)
			}
		}
		if value.Minimum != nil && value.Maximum != nil && *value.Minimum > *value.Maximum {
			return fmt.Errorf("%s minimum exceeds maximum", path)
		}
	case typedNullShape:
	case typedConstShape:
		if _, err := json.Marshal(value.Value); err != nil {
			return fmt.Errorf("%s const is not JSON-encodable: %w", path, err)
		}
	case typedArrayShape:
		if value.Items == nil {
			return fmt.Errorf("%s.Items is required", path)
		}
		if value.MinItems != nil && *value.MinItems < 0 || value.MaxItems != nil && *value.MaxItems < 0 {
			return fmt.Errorf("%s item lengths must be nonnegative", path)
		}
		if value.MinItems != nil && value.MaxItems != nil && *value.MinItems > *value.MaxItems {
			return fmt.Errorf("%s minItems exceeds maxItems", path)
		}
		return validateShape(value.Items, path+".Items")
	case typedObjectShape:
		seen := make(map[string]struct{})
		for i := range value.Fields {
			field := &value.Fields[i]
			if field.Name == "" {
				return fmt.Errorf("%s.Fields[%d].Name is required", path, i)

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read the wrapped json.Marshal cause to see which type failed to encode.
  2. Replace the const Value with a JSON-native Go value (string, number, bool, nil, or composed slices/maps).
  3. If a custom MarshalJSON is involved, fix it to handle the value or marshal the underlying concrete value instead.
  4. Pre-marshal the value in a test to catch this before registration.

Example fix

// before
shape := typedConstShape{Value: make(chan int)} // not JSON-encodable
// after
shape := typedConstShape{Value: 42}
Defensive patterns

Strategy: validation

Validate before calling

func jsonEncodableConst(v any) error {
    if _, err := json.Marshal(v); err != nil {
        return fmt.Errorf("const value not JSON-encodable: %w", err)
    }
    return nil
}
// if err := jsonEncodableConst(shape.Value); err != nil { return err }

Type guard

func isJSONNative(v any) bool {
    switch v.(type) {
    case nil, string, bool, float64, int, int64, json.RawMessage:
        return true
    }
    rv := reflect.ValueOf(v)
    switch rv.Kind() {
    case reflect.Slice, reflect.Array, reflect.Map, reflect.Struct, reflect.Pointer:
        return true // still verify via json.Marshal for custom encoders
    default:
        return false // chan, func, complex, etc.
    }
}

Prevention

When it happens

Trigger: An explicit Output.Data.Shape or DataField.Shape override sets typedConstShape.Value to a channel, func, complex number, or a type whose MarshalJSON returns an error; json.Marshal inside validateShape then fails and the cause is wrapped.

Common situations: Using a custom type with a MarshalJSON implementation that errors for the given value (e.g. an invalid time or an enum without a mapping); accidentally embedding a non-serializable Go value like a func or channel in the const.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/3c0cb8cf023c780e. Report an issue: GitHub.