googleapis/mcp-toolbox · error
failed to unmarshal operation JSON to map: %w
Error message
failed to unmarshal operation JSON to map: %w
What it means
After GetOperation successfully marshals the operation with protojson, it decodes the JSON bytes into a map[string]any for the caller. If the JSON produced cannot be unmarshaled into a map (corrupt or non-object payload), this wrapped error is returned. Practically unreachable with valid protojson output, but it hardens the conversion path.
Source
Thrown at internal/sources/dataplex/dataplex.go:927
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)
}
// Fallback to listing and returning the latest job (PageSize: 1)
parent := fmt.Sprintf("projects/%s/locations/%s/dataScans/%s", s.ProjectID(), location, scanID)
req := &dataplexpb.ListDataScanJobsRequest{View on GitHub (pinned to 8cc6e09de2)
Solutions
- Inspect the wrapped error from json.Unmarshal for the exact cause
- Re-run with a stock protojson.Marshal to confirm output is a JSON object
- Ensure no middleware rewrites the marshaled bytes
- Update the dataplex client/proto dependencies if a known bug applies
Defensive patterns
Strategy: try-catch
Validate before calling
if len(bytes) == 0 || bytes[0] != '{' { return errors.New("operation payload is not a JSON object") } Try / catch
opData, err := src.GetOperation(ctx, name)
if err != nil {
if strings.Contains(err.Error(), "unmarshal operation JSON") {
// fall back to raw operation proto inspection
}
return err
} Prevention
- Use stock protojson without intermediaries
- Avoid post-processing the marshaled bytes
- Report persistent failures with the wrapped cause to SDK maintainers
When it happens
Trigger: Calling GetOperation when the intermediate JSON bytes from protojson.Marshal are not a valid JSON object (only possible with corrupted output or replaced marshaler behavior).
Common situations: Custom/patched protojson behavior; intermediary mutation of bytes; extremely rare in production — mostly seen in mocked or instrumented clients.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- operation finished with error but could not marshal error ob
- failed to initialize dataplex client: %w
- failed to create Dataplex client for project %q: %w
- failed to get dataplex client: %w
- could not unmarshal response as json: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/b5ceee072c7a15d6.
Report an issue: GitHub.