googleapis/mcp-toolbox · error
error generating logs url: %v
Error message
error generating logs url: %v
What it means
ToJobs builds a Cloud Console logs URL for each job via JobLogsURLFromProto; when that helper errors (typically because the job proto lacks placement info), ToJobs aborts the whole conversion and returns this wrapped message with %v. Note it uses %v, so the original error is not unwrap-able programmatically.
Source
Thrown at internal/sources/dataproc/dataproc.go:331
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)
}
status := "STATE_UNSPECIFIED"
subStatus := ""
var startTime, endTime string
if jobPb.Status != nil {
status = jobPb.Status.State.Enum().String()
subStatus = jobPb.Status.Substate.Enum().String()
}
var sTime, eTime time.Time
for _, s := range jobPb.StatusHistory {
t := s.StateStartTime.AsTime()
if sTime.IsZero() || t.Before(sTime) {
sTime = t
}
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Check the job proto: ensure jobs have Placement.ClusterName set (query a specific job via GetJob to inspect)
- If you control job creation, verify jobs are submitted against a cluster so placement is recorded
- Handle the error per-job by falling back to a URL-less result instead of failing the whole list
- Report upstream if the Dataproc API legitimately returns jobs without placement
Example fix
// before
logsUrl, err := JobLogsURLFromProto(jobPb, region)
if err != nil {
return nil, fmt.Errorf("error generating logs url: %v", err)
}
// after
logsUrl, err := JobLogsURLFromProto(jobPb, region)
if err != nil {
logsUrl = "" // degrade gracefully instead of failing the whole batch
} Defensive patterns
Strategy: fallback
Validate before calling
if job.GetPlacement() == nil {
// skip URL generation for this job
} Type guard
func hasPlacement(j *dataprocpb.Job) bool { return j != nil && j.GetPlacement() != nil } Try / catch
logsUrl, err := JobLogsURLFromProto(jobPb, region)
if err != nil {
logsUrl = "" // fall back to empty URL rather than failing the batch
} Prevention
- Check job.Placement before requesting a logs URL
- Handle URL generation per-job instead of failing the whole list
- Verify jobs were submitted against a cluster so placement is populated
When it happens
Trigger: Calling ListJobs (which calls ToJobs) when any returned job's dataprocpb.Job has a nil Placement field, so JobLogsURLFromProto cannot determine the cluster name for the logs URL.
Common situations: Jobs in unusual states or created through paths that omit placement metadata; partially deleted clusters; jobs returned by filters where placement was never populated.
Related errors
- job has no placement info
- failed to create dataproc client: %w
- failed to create longrunning client: %w
- failed to create dataproc job client: %w
- failed to list clusters: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/4bb1a62803829610.
Report an issue: GitHub.