{"record":{"id":"673fa57f9c874c5a","repo":"apache/beam","slug":"unable-to-decode-pardopayload","errorCode":null,"errorMessage":"unable to decode ParDoPayload","messagePattern":"unable to decode ParDoPayload","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/runners/prism/internal/stage.go","lineNumber":382,"sourceCode":"\t\t}\n\t\tslog.Debug(\"finalized bundle\", \"bundle\", rb)\n\t}\n\tb.OutputData = engine.TentativeData{} // Clear the data.\n\treturn nil\n}\n\nfunc getSideInputs(t *pipepb.PTransform) (map[string]*pipepb.SideInput, error) {\n\tswitch t.GetSpec().GetUrn() {\n\tcase urns.TransformParDo, urns.TransformProcessSizedElements, urns.TransformPairWithRestriction, urns.TransformSplitAndSize, urns.TransformTruncate:\n\t\t// Intentionally empty since these are permitted to have side inputs.\n\tdefault:\n\t\t// Nothing else is allowed to have side inputs.\n\t\treturn nil, nil\n\t}\n\t// TODO, memoize this, so we don't need to repeatedly unmarshal.\n\tpardo := &pipepb.ParDoPayload{}\n\tif err := (proto.UnmarshalOptions{}).Unmarshal(t.GetSpec().GetPayload(), pardo); err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to decode ParDoPayload\")\n\t}\n\treturn pardo.GetSideInputs(), nil\n}\n\nfunc portFor(wInCid string, wk *worker.W) []byte {\n\tsourcePort := &fnpb.RemoteGrpcPort{\n\t\tCoderId: wInCid,\n\t\tApiServiceDescriptor: &pipepb.ApiServiceDescriptor{\n\t\t\tUrl: wk.Endpoint(),\n\t\t},\n\t}\n\tsourcePortBytes, err := proto.Marshal(sourcePort)\n\tif err != nil {\n\t\tslog.Error(\"bad port\", slog.Any(\"error\", err), slog.String(\"endpoint\", sourcePort.ApiServiceDescriptor.GetUrl()))\n\t}\n\treturn sourcePortBytes\n}\n","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/prism/internal/stage.go#L364-L400","documentation":"getSideInputs extracts the SideInputs map from a transform's ParDoPayload; this error is returned if the payload fails proto unmarshaling. Callers computeFacts and handleSideInput rely on it to know which inputs are side inputs and how to read them.","triggerScenarios":"Calling getSideInputs on a transform whose spec payload is not decodable as a ParDoPayload — wrong payload for the URN, or truncated/corrupt bytes.","commonSituations":"Version skew between the SDK that produced the pipeline and prism; manually built pipeline protos attaching the wrong payload type to a ParDo URN.","solutions":["Match SDK and prism Beam versions","Verify the transform URN corresponds to a ParDoPayload payload","Dump and decode the payload bytes locally to confirm corruption"],"exampleFix":"// cause wrapping for debuggability\nif err := (proto.UnmarshalOptions{}).Unmarshal(t.GetSpec().GetPayload(), pardo); err != nil {\n    return nil, fmt.Errorf(\"unable to decode ParDoPayload: %w\", err)\n}","handlingStrategy":"validation","validationCode":"sis, err := getSideInputs(t)\nif err != nil {\n    return fmt.Errorf(\"transform %v: %w\", tID, err)\n}","typeGuard":null,"tryCatchPattern":"if sis, err := getSideInputs(t); err != nil {\n    slog.Error(\"side input decode failed\", \"transform\", tID, \"err\", err)\n    return err\n}","preventionTips":["Keep payloads well-formed; regenerate pipelines rather than patching bytes","Match SDK/runner versions","Confirm ParDo transforms carry ParDoPayload specs"],"tags":["go","beam","protobuf","side-input"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}