{"record":{"id":"0ebde7cd433c32aa","repo":"googleapis/mcp-toolbox","slug":"failed-to-marshal-operation-to-json-w","errorCode":null,"errorMessage":"failed to marshal operation to JSON: %w","messagePattern":"failed to marshal operation to JSON: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/dataplex/dataplex.go","lineNumber":922,"sourceCode":"\treturn s.DataScanClient.GetDataScan(ctx, req)\n}\n\nfunc (s *Source) GetOperation(ctx context.Context, opName string) (map[string]any, error) {\n\tif !operationNameRegex.MatchString(opName) {\n\t\treturn nil, fmt.Errorf(\"invalid operation name format: %q (expected projects/*/locations/*/operations/*)\", opName)\n\t}\n\n\treq := &longrunningpb.GetOperationRequest{\n\t\tName: opName,\n\t}\n\top, err := s.DataScanClient.LROClient.GetOperation(ctx, req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbytes, err := protojson.Marshal(op)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal operation to JSON: %w\", err)\n\t}\n\n\tvar opData map[string]any\n\tif err := json.Unmarshal(bytes, &opData); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal operation JSON to map: %w\", err)\n\t}\n\n\treturn opData, nil\n}\n\nfunc (s *Source) GetJobStatus(ctx context.Context, location, scanID, jobID string) (*dataplexpb.DataScanJob, error) {\n\t// If jobID is provided, fetch that specific job directly!\n\tif jobID != \"\" {\n\t\tname := fmt.Sprintf(\"projects/%s/locations/%s/dataScans/%s/jobs/%s\", s.ProjectID(), location, scanID, jobID)\n\t\treq := &dataplexpb.GetDataScanJobRequest{\n\t\t\tName: name,\n\t\t}\n\t\treturn s.DataScanClient.GetDataScanJob(ctx, req)","sourceCodeStart":904,"sourceCodeEnd":940,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/dataplex/dataplex.go#L904-L940","documentation":"GetOperation fetches a Dataplex long-running operation and serializes it with protojson to return JSON to the caller. If protojson cannot marshal the returned *longrunningpb.Operation (nil pointer or invalid proto state), the error is wrapped as 'failed to marshal operation to JSON'. This is an internal serialization failure, not an API error.","triggerScenarios":"Calling GetOperation when the Dataplex client returns an operation value that protojson cannot encode — typically a nil operation pointer or a corrupt/invalid proto message.","commonSituations":"Operation not found paths returning nil without error from a stub; passing an operation from a mismatched proto package version; mocking the DataScanClient with an invalid message.","solutions":["Check that the operation name passed to GetOperation exists and the client returned a non-nil operation","Verify the google.golang.org/genproto dataplex/longrunning proto versions are consistent (go mod tidy / go get -u)","If using a mock client, ensure the stub returns a valid *longrunningpb.Operation","Log the underlying wrapped error (%w) to see the exact protojson failure"],"exampleFix":"// before\nop, err := src.GetOperation(ctx, \"\")\n// after\nif opName == \"\" {\n    return errors.New(\"operation name is required\")\n}\nop, err := src.GetOperation(ctx, opName)","handlingStrategy":"try-catch","validationCode":"if op == nil || op.GetName() == \"\" { return errors.New(\"no operation returned\") }","typeGuard":"op, ok := resp.(*longrunningpb.Operation); if !ok || op == nil { ... }","tryCatchPattern":"op, err := src.GetOperation(ctx, name)\nif err != nil {\n\tvar uerr interface{ Unwrap() error }\n\tif errors.As(err, &uerr) { log.Printf(\"underlying: %v\", uerr) }\n\treturn fmt.Errorf(\"get operation failed: %w\", err)\n}","preventionTips":["Never call GetOperation with an empty operation name","Keep proto/genproto dependencies aligned across modules","Validate mocks return fully-formed Operation messages"],"tags":["dataplex","protojson","serialization","gcp"],"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"}