googleapis/mcp-toolbox · error
failed to list jobs: %w
Error message
failed to list jobs: %w
What it means
ListJobs wraps any error returned by the Dataproc pager while iterating a page of jobs (pager.NextPage). This library wraps the underlying Google API error with %w so callers can inspect it with errors.Is/As. It indicates the RPC to the Dataproc API failed while listing jobs in the configured region.
Source
Thrown at internal/sources/dataproc/dataproc.go:313
if jobStateMatcher != "" {
if v, ok := dataprocpb.ListJobsRequest_JobStateMatcher_value[jobStateMatcher]; ok {
req.JobStateMatcher = dataprocpb.ListJobsRequest_JobStateMatcher(v)
} else {
return nil, fmt.Errorf("invalid jobStateMatcher: %s. Supported values: ALL, ACTIVE, NON_ACTIVE", jobStateMatcher)
}
}
it := client.ListJobs(ctx, req)
ps := 0
if pageSize != nil {
ps = *pageSize
}
pager := iterator.NewPager(it, ps, req.PageToken)
var jobPbs []*dataprocpb.Job
nextPageToken, err := pager.NextPage(&jobPbs)
if err != nil {
return nil, fmt.Errorf("failed to list jobs: %w", err)
}
jobs, err := ToJobs(jobPbs, s.Region)
if err != nil {
return nil, err
}
return ListJobsResponse{Jobs: jobs, NextPageToken: nextPageToken}, nil
}
// ToJobs converts a slice of protobuf Job messages to a slice of Job structs.
func ToJobs(jobPbs []*dataprocpb.Job, region string) ([]Job, error) {
jobs := make([]Job, 0, len(jobPbs))
for _, jobPb := range jobPbs {
consoleUrl := JobConsoleURLFromProto(jobPb, region)
logsUrl, err := JobLogsURLFromProto(jobPb, region)
if err != nil {
return nil, fmt.Errorf("error generating logs url: %v", err)View on GitHub (pinned to 8cc6e09de2)
Solutions
- Unwrap the error (errors.Unwrap / %v formatting) to see the underlying gRPC status and act on it
- Verify the region in the Dataproc source config matches where the cluster/jobs live (use 'global' or the correct regional endpoint)
- Grant the caller's service account the dataproc.jobs.list permission (roles/dataproc.viewer or roles/dataproc.editor)
- Enable the Dataproc API on the project and check quota/limits
- Retry on transient errors with backoff
Example fix
// before
jobs, err := toolbox.ListJobs(ctx, pageSize, token)
// after
jobs, err := toolbox.ListJobs(ctx, pageSize, token)
if err != nil {
log.Printf("list jobs failed: %v", err) // wrapped gRPC error shows real cause
if st, ok := status.FromError(errors.Unwrap(err)); ok && st.Code() == codes.PermissionDenied { ... }
} Defensive patterns
Strategy: try-catch
Validate before calling
if region == "" || projectID == "" {
return fmt.Errorf("region and projectId must be set before listing Dataproc jobs")
} Try / catch
jobs, err := svc.ListJobs(ctx, pageSize, token)
if err != nil {
if u := errors.Unwrap(err); u != nil && strings.Contains(u.Error(), "PermissionDenied") {
// fix IAM
}
return fmt.Errorf("listing dataproc jobs: %w", err)
} Prevention
- Set the correct region in the source config before calling
- Grant roles/dataproc.viewer to the service account
- Enable the Dataproc API on the project
- Retry transient failures with exponential backoff
When it happens
Trigger: Calling ListJobs when the Dataproc API call fails: invalid/missing region, disabled Dataproc API, insufficient IAM permissions (dataproc.jobs.list), network failure, or an invalid page token.
Common situations: Misconfigured region in the source config (e.g. region set to a location with no projects access), service account lacking roles/dataproc.viewer, quota exhaustion, or transient 5xx from the Dataproc API.
Related errors
- failed to get job: %w
- error cloning instance: %w
- error creating database: %w
- error creating user: %w
- error getting instance: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/1135077fd004ae0c.
Report an issue: GitHub.