vitessio/vitess · error

protojson error: %v

Error message

protojson error: %v

What it means

MarshalJSON's proto branch uses protojson.MarshalOptions to encode protobuf objects; a protojson failure (invalid proto message, wrong concrete type, or unsupported field) is wrapped as 'protojson error'. Unlike encoding/json, protojson can fail on invalid proto3 messages.

Source

Thrown at go/vt/vtctl/vtctl.go:3978

//
//	updated and mixed types will use jsonpb as well.
func MarshalJSON(obj any) (data []byte, err error) {
	switch obj := obj.(type) {
	case proto.Message:
		// Note: We also end up in this case if "obj" is NOT a proto.Message but
		// has an anonymous (embedded) field of the type "proto.Message".
		// In that case jsonpb may panic if the "obj" has non-exported fields.

		// Marshal the protobuf message.
		data, err = protojson.MarshalOptions{
			Multiline:       true,
			Indent:          "  ",
			UseProtoNames:   true,
			UseEnumNumbers:  true,
			EmitUnpopulated: true,
		}.Marshal(obj)
		if err != nil {
			return nil, fmt.Errorf("protojson error: %v", err)
		}
	case []string:
		if len(obj) == 0 {
			return []byte{'[', ']'}, nil
		}
		data, err = json.MarshalIndent(obj, "", "  ")
		if err != nil {
			return nil, fmt.Errorf("json error: %v", err)
		}
	default:
		data, err = json.MarshalIndent(obj, "", "  ")
		if err != nil {
			return nil, fmt.Errorf("json error: %v", err)
		}
	}

	return data, nil
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the wrapped %v error for the specific protojson failure reason
  2. Verify the object being marshaled is a valid, populated protobuf message
  3. Ensure generated proto code and google.golang.org/protobuf versions are in sync (go mod tidy/upgrade)

Example fix

// before
return nil, fmt.Errorf("protojson error: %v", err)
// after
return nil, vterrors.Wrapf(err, vtrpcpb.Code_INTERNAL, "protojson error marshaling %T", obj)
Defensive patterns

Strategy: try-catch

Try / catch

data, err := MarshalJSON(val)
if err != nil {
	if strings.Contains(err.Error(), "protojson error") {
		log.Warnf("protojson failed for %T, using fallback encoder", val)
		return json.Marshal(val)
	}
	return err
}

Prevention

When it happens

Trigger: A vtctl command printing a protobuf value via MarshalJSON where protojson.Marshal rejects the object (e.g. nil proto message contents or a type not registered).

Common situations: Passing a non-proto value into the protobuf branch by mistake; corrupted protobuf data from topo; version mismatch between generated pb code and protojson library.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/6680f4b4a52209c3. Report an issue: GitHub.