{"record":{"id":"f2200c3d031eff37","repo":"googleapis/mcp-toolbox","slug":"failed-to-marshal-cluster-to-json-w","errorCode":null,"errorMessage":"failed to marshal cluster to JSON: %w","messagePattern":"failed to marshal cluster to JSON: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/dataproc/dataproc.go","lineNumber":239,"sourceCode":"\n// GetCluster gets a single cluster.\nfunc (s *Source) GetCluster(ctx context.Context, clusterName string) (any, error) {\n\tclient := s.GetClusterControllerClient()\n\n\treq := &dataprocpb.GetClusterRequest{\n\t\tProjectId:   s.Project,\n\t\tRegion:      s.Region,\n\t\tClusterName: clusterName,\n\t}\n\n\tclusterPb, err := client.GetCluster(ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get cluster: %w\", err)\n\t}\n\n\tjsonBytes, err := protojson.Marshal(clusterPb)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal cluster to JSON: %w\", err)\n\t}\n\n\tvar result map[string]any\n\tif err := json.Unmarshal(jsonBytes, &result); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal cluster JSON: %w\", err)\n\t}\n\n\tconsoleUrl := ClusterConsoleURLFromProto(clusterPb, s.Region)\n\tlogsUrl := ClusterLogsURLFromProto(clusterPb, s.Region)\n\n\twrappedResult := map[string]any{\n\t\t\"consoleUrl\": consoleUrl,\n\t\t\"logsUrl\":    logsUrl,\n\t\t\"cluster\":    result,\n\t}\n\n\treturn wrappedResult, nil\n}","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/dataproc/dataproc.go#L221-L257","documentation":"Thrown by GetCluster when protojson.Marshal fails to serialize the returned Cluster proto into JSON. This is rare because the input is a valid proto from a successful RPC; it typically indicates an unexpected/nil proto or an incompatibility between the dataprocpb version and the protojson behavior.","triggerScenarios":"protojson.Marshal(clusterPb) receives a nil or invalidly-formed Cluster proto, or a mismatched generated proto type (version skew between cloud.google.com/go/dataproc module and google.golang.org/protobuf).","commonSituations":"Dependency version skew after a Go module upgrade; manually constructed sources in tests passing nil protos; corrupted in-memory state.","solutions":["Run `go mod tidy` and update cloud.google.com/go/dataproc and google.golang.org/protobuf to compatible versions.","Check that GetCluster returned a non-nil proto before marshaling (defensive nil check).","Report the issue with the full error if it reproduces with pinned, up-to-date dependencies."],"exampleFix":"// before (no nil check)\nclusterPb, err := client.GetCluster(ctx, req)\nif err != nil { ... }\njsonBytes, err := protojson.Marshal(clusterPb)\n\n// after (defensive nil check)\nif clusterPb == nil {\n    return nil, fmt.Errorf(\"received nil cluster proto\")\n}\njsonBytes, err := protojson.Marshal(clusterPb)","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"if clusterPb == nil {\n    return errors.New(\"nil cluster proto returned by GetCluster\")\n}","tryCatchPattern":"cluster, err := src.GetCluster(ctx, name)\nif err != nil && strings.Contains(err.Error(), \"marshal cluster to JSON\") {\n    // serialization bug: pin/update protobuf + dataproc module versions, report upstream\n    return err\n}","preventionTips":["Keep cloud.google.com/go/dataproc and google.golang.org/protobuf versions in sync.","After dependency upgrades, run integration tests covering get-cluster.","Report reproducible marshal failures upstream with the wrapped error."],"tags":["dataproc","serialization","protojson"],"backgroundTag":"proto-serialization-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}