hashicorp/nomad · error

must pass non-nil job

Error message

must pass non-nil job

What it means

Guard in Jobs.PlanOpts: the job planning API requires a non-nil *Job; calling Plan/PlanOpts with a nil job pointer is a client programming error, so the request never reaches the server.

Source

Thrown at api/jobs.go:502

		return "", nil, err
	}
	return resp.EvalID, wm, nil
}

// PlanOptions is used to pass through job planning parameters
type PlanOptions struct {
	Diff           bool
	PolicyOverride bool
}

func (j *Jobs) Plan(job *Job, diff bool, q *WriteOptions) (*JobPlanResponse, *WriteMeta, error) {
	opts := PlanOptions{Diff: diff}
	return j.PlanOpts(job, &opts, q)
}

func (j *Jobs) PlanOpts(job *Job, opts *PlanOptions, q *WriteOptions) (*JobPlanResponse, *WriteMeta, error) {
	if job == nil {
		return nil, nil, errors.New("must pass non-nil job")
	}
	if job.ID == nil {
		return nil, nil, errors.New("job is missing ID")
	}

	// Setup the request
	req := &JobPlanRequest{
		Job: job,
	}
	if opts != nil {
		req.Diff = opts.Diff
		req.PolicyOverride = opts.PolicyOverride
	}

	var resp JobPlanResponse
	wm, err := j.client.put("/v1/job/"+url.PathEscape(*job.ID)+"/plan", req, &resp, q)
	if err != nil {
		return nil, nil, err

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check job != nil before calling PlanOpts or Plan
  2. Ensure the code path that constructs the *Job always returns a valid job or an error
  3. If loading from file, use api.Parse and stop on its error before planning

Example fix

// before
j.PlanOpts(job, &opts, q)
// after
if job == nil {
    return fmt.Errorf("cannot plan: job is nil")
}
j.PlanOpts(job, &opts, q)
Defensive patterns

Strategy: validation

Validate before calling

func canPlan(job *api.Job) bool { return job != nil }

Type guard

func jobIsNonNil(j *api.Job) (*api.Job, bool) {
    if j == nil { return nil, false }
    return j, true
}

Try / catch

resp, _, err := jobs.PlanOpts(job, &opts, q)
if err != nil {
    return fmt.Errorf("plan failed: %w", err)
}

Prevention

When it happens

Trigger: Calling j.PlanOpts(nil, opts, q) directly, or calling j.Plan(job, diff, q) where job was produced by an earlier call that returned nil on a handled error path.

Common situations: Structuring config where the job is conditionally built and a nil slips through; parsing a job spec file that failed silently; refactoring that removed an earlier nil check.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/1070da423b9ce9ba. Report an issue: GitHub.