apache/beam · error

bad type: %v, want %v

Error message

bad type: %v, want %v

What it means

protox.Unpack verifies that the Any proto's TypeUrl matches the expected url before unmarshaling its payload into ret. If they differ it returns this error without touching ret, preventing unmarshaling bytes of the wrong message type into the caller's message.

Source

Thrown at sdks/go/pkg/beam/core/util/protox/any.go:32

// limitations under the License.

package protox

import (
	"github.com/apache/beam/sdks/v2/go/pkg/beam/internal/errors"
	"google.golang.org/protobuf/proto"
	protobuf "google.golang.org/protobuf/types/known/anypb"
	protobufw "google.golang.org/protobuf/types/known/wrapperspb"
)

const (
	bytesValueTypeURL = "type.googleapis.com/google.protobuf.BytesValue"
)

// Unpack decodes a proto.
func Unpack(data *protobuf.Any, url string, ret proto.Message) error {
	if data.TypeUrl != url {
		return errors.Errorf("bad type: %v, want %v", data.TypeUrl, url)
	}
	return proto.Unmarshal(data.Value, ret)
}

// UnpackProto decodes a BytesValue wrapped proto.
func UnpackProto(data *protobuf.Any, ret proto.Message) error {
	buf, err := UnpackBytes(data)
	if err != nil {
		return err
	}
	return proto.Unmarshal(buf, ret)
}

// PackProto encodes a proto message and wraps into a BytesValue.
func PackProto(in proto.Message) (*protobuf.Any, error) {
	b, err := proto.Marshal(in)
	if err != nil {
		return nil, err

View on GitHub (pinned to 12126d8942)

Solutions

  1. Make the expected url match how the Any was created: use protox.UnpackProto for payloads packed via PackProto, or pass bytesValueTypeURL to Unpack
  2. Use protox.Pack/Unpack pairs consistently on sender and receiver (Pack with the same message type and URL)
  3. Log data.TypeUrl on failure and compare against the constant you pass; fix the constant or the packing side
  4. Regenerate/republish the payload if the producer switched message types

Example fix

// before
var req pb.MyRequest
protox.Unpack(data, "type.googleapis.com/MyRequest", &req) // TypeUrl is BytesValue
// after
var wrapped pb.BytesValue
protox.UnpackProto(data, &wrapped) // or protox.Unpack(data, protox.BytesValueTypeURL, &wrapped)
var req pb.MyRequest
proto.Unmarshal(wrapped.Value, &req)
Defensive patterns

Strategy: type-guard

Validate before calling

// verify the Any carries the expected URL before unpacking
if data.GetTypeUrl() != "type.googleapis.com/google.protobuf.BytesValue" {
    return fmt.Errorf("unexpected payload type: %s", data.GetTypeUrl())
}

Type guard

func isBytesValueAny(data *anypb.Any) bool {
    return data.GetTypeUrl() == "type.googleapis.com/google.protobuf.BytesValue"
}

Try / catch

if err := protox.Unpack(data, url, msg); err != nil {
    if strings.HasPrefix(err.Error(), "bad type:") {
        return fmt.Errorf("payload type mismatch: got %s, want %s", data.GetTypeUrl(), url)
    }
    return err
}

Prevention

When it happens

Trigger: Calling protox.Unpack(data, url, ret) where data.TypeUrl != url — e.g. unpacking an Any produced by protox.PackProto (BytesValue wrapper, url "type.googleapis.com/google.protobuf.BytesValue") with Unpack, or passing the wrong expected URL for the serialized message.

Common situations: Mixing Unpack and UnpackProto: data was packed with PackProto but unpacked without the BytesValue type URL; sender upgraded/repacked the payload with a different message type; hard-coded URL string that doesn't match the proto package path of the actual message.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/c3f3f8da3117e4c4. Report an issue: GitHub.