googleapis/mcp-toolbox · error
failed to marshal operation to JSON
Error message
failed to marshal operation to JSON: %w
What it means
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.
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
Example fix
// before
op, err := src.GetOperation(ctx, "")
// after
if opName == "" {
return errors.New("operation name is required")
}
op, err := src.GetOperation(ctx, opName) Defensive patterns
Strategy: try-catch
Validate before calling
if op == nil || op.GetName() == "" { return errors.New("no operation returned") } Type guard
op, ok := resp.(*longrunningpb.Operation); if !ok || op == nil { ... } Try / catch
op, err := src.GetOperation(ctx, name)
if err != nil {
var uerr interface{ Unwrap() error }
if errors.As(err, &uerr) { log.Printf("underlying: %v", uerr) }
return fmt.Errorf("get operation failed: %w", err)
} Prevention
- Never call GetOperation with an empty operation name
- Keep proto/genproto dependencies aligned across modules
- Validate mocks return fully-formed Operation messages
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- dataplex catalog client is nil
- failed to create Dataplex client for project
- failed to create Dataplex client for project
- failed to create Dataplex DataProduct client for project
- failed to create Dataplex DataScan client for project
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/0ebde7cd433c32aa.
Report an issue: GitHub.
Appendix: source
Thrown at internal/sources/dataplex/dataplex.go:922
return s.DataScanClient.GetDataScan(ctx, req)
}
func (s *Source) GetOperation(ctx context.Context, opName string) (map[string]any, error) {
if !operationNameRegex.MatchString(opName) {
return nil, fmt.Errorf("invalid operation name format: %q (expected projects/*/locations/*/operations/*)", opName)
}
req := &longrunningpb.GetOperationRequest{
Name: opName,
}
op, err := s.DataScanClient.LROClient.GetOperation(ctx, req)
if err != nil {
return nil, err
}
bytes, err := protojson.Marshal(op)
if err != nil {
return nil, fmt.Errorf("failed to marshal operation to JSON: %w", err)
}
var opData map[string]any
if err := json.Unmarshal(bytes, &opData); err != nil {
return nil, fmt.Errorf("failed to unmarshal operation JSON to map: %w", err)
}
return opData, nil
}
func (s *Source) GetJobStatus(ctx context.Context, location, scanID, jobID string) (*dataplexpb.DataScanJob, error) {
// If jobID is provided, fetch that specific job directly!
if jobID != "" {
name := fmt.Sprintf("projects/%s/locations/%s/dataScans/%s/jobs/%s", s.ProjectID(), location, scanID, jobID)
req := &dataplexpb.GetDataScanJobRequest{
Name: name,
}
return s.DataScanClient.GetDataScanJob(ctx, req)View on GitHub (pinned to 8cc6e09de2)