googleapis/mcp-toolbox · warning

job has no placement info

Error message

job has no placement info

What it means

JobLogsURLFromProto builds a Console Cloud Logging URL for a job and requires jobPb.Placement.ClusterName. If the Job proto's Placement field is nil, there is no cluster name to embed in the URL, so this sentinel error is returned. It propagates to ToJobs (ListJobs) and GetJob.

Source

Thrown at internal/sources/dataproc/url.go:68

			if !stateStartTime.IsZero() {
				endTime = stateStartTime
				startTime = stateStartTime.Add(-1 * time.Hour)
			}
		}
	}

	return ClusterLogsURL(clusterPb.ProjectId, region, clusterPb.ClusterName, clusterPb.ClusterUuid, startTime, endTime)
}

// JobConsoleURLFromProto builds a URL to the Google Cloud Console linking to the job page.
func JobConsoleURLFromProto(jobPb *dataprocpb.Job, region string) string {
	return JobConsoleURL(jobPb.Reference.ProjectId, region, jobPb.Reference.JobId)
}

// JobLogsURLFromProto builds a URL to the Google Cloud Console showing Cloud Logging for the given job.
func JobLogsURLFromProto(jobPb *dataprocpb.Job, region string) (string, error) {
	if jobPb.Placement == nil {
		return "", fmt.Errorf("job has no placement info")
	}
	clusterName := jobPb.Placement.ClusterName
	projectID := jobPb.Reference.ProjectId
	jobID := jobPb.Reference.JobId

	var startTime, endTime time.Time
	// Find min start time from history
	for _, s := range jobPb.StatusHistory {
		t := s.StateStartTime.AsTime()
		if startTime.IsZero() || t.Before(startTime) {
			startTime = t
		}
	}
	// Also check current status
	if jobPb.Status != nil {
		t := jobPb.Status.StateStartTime.AsTime()
		if startTime.IsZero() || t.Before(startTime) {
			startTime = t

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Guard the call: check jobPb.Placement != nil before calling JobLogsURLFromProto
  2. In tests, populate dataprocpb.Job{Placement: &dataprocpb.JobPlacement{ClusterName: "..."}}
  3. Fall back to a console URL variant that does not require the cluster name when placement is absent

Example fix

// before
logsUrl, err := JobLogsURLFromProto(jobPb, region)
// after
var logsUrl string
if jobPb.GetPlacement() != nil {
	logsUrl, _ = JobLogsURLFromProto(jobPb, region)
}
Defensive patterns

Strategy: type-guard

Validate before calling

if jobPb.GetPlacement() == nil || jobPb.GetPlacement().GetClusterName() == "" {
	return "", fmt.Errorf("job has no placement info")
}

Type guard

func jobHasPlacement(j *dataprocpb.Job) bool {
	return j != nil && j.GetPlacement() != nil && j.GetPlacement().GetClusterName() != ""
}

Try / catch

var logsUrl string
if jobHasPlacement(jobPb) {
	logsUrl, _ = JobLogsURLFromProto(jobPb, region)
}

Prevention

When it happens

Trigger: Passing a *dataprocpb.Job with Placement == nil to JobLogsURLFromProto — directly in tests (TestJobLogsURLFromProto) or indirectly via ToJobs/GetJob when the API returns a placement-less job.

Common situations: Unit tests constructing minimal Job protos without placement; API responses for jobs in edge states lacking placement metadata.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/51f0f5f038f498b2. Report an issue: GitHub.