{"record":{"id":"4919af58639a921b","repo":"hashicorp/nomad","slug":"can-t-force-run-non-tracked-job-q-s","errorCode":null,"errorMessage":"can't force run non-tracked job %q (%s)","messagePattern":"can't force run non-tracked job %q \\((.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/periodic.go","lineNumber":299,"sourceCode":"// ForceEval causes the periodic job to be evaluated immediately and returns the\n// subsequent eval.\nfunc (p *PeriodicDispatch) ForceEval(namespace, jobID string) (*structs.Evaluation, error) {\n\tp.l.Lock()\n\n\t// Do nothing if not enabled\n\tif !p.enabled {\n\t\tp.l.Unlock()\n\t\treturn nil, fmt.Errorf(\"periodic dispatch disabled\")\n\t}\n\n\ttuple := structs.NamespacedID{\n\t\tID:        jobID,\n\t\tNamespace: namespace,\n\t}\n\tjob, tracked := p.tracked[tuple]\n\tif !tracked {\n\t\tp.l.Unlock()\n\t\treturn nil, fmt.Errorf(\"can't force run non-tracked job %q (%s)\", jobID, namespace)\n\t}\n\n\tp.l.Unlock()\n\treturn p.createEval(job, time.Now().In(job.Periodic.GetLocation()))\n}\n\n// shouldRun returns whether the long lived run function should run.\nfunc (p *PeriodicDispatch) shouldRun() bool {\n\tp.l.RLock()\n\tdefer p.l.RUnlock()\n\treturn p.enabled\n}\n\n// run is a long-lived function that waits till a job's periodic spec is met and\n// then creates an evaluation to run the job.\nfunc (p *PeriodicDispatch) run(ctx context.Context, updateCh <-chan struct{}) {\n\tvar launchCh <-chan time.Time\n\tfor p.shouldRun() {","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/periodic.go#L281-L317","documentation":"PeriodicDispatch.ForceEval was asked to force-run a periodic job that is not in the dispatcher's tracked map; the job was never added via Add (or the dispatcher was restarted/disabled and lost tracking), so it cannot be dispatched immediately.","triggerScenarios":"Calling ForceEval with a jobID/namespace that isn't in p.tracked — the job isn't periodic, doesn't exist, was deregistered, or the wrong namespace was passed.","commonSituations":"Typo in job ID; querying the default namespace while the job lives in another; job was deleted between listing and force-run; forcing a non-periodic job bypassing the endpoint's IsPeriodic check.","solutions":["Ensure the job is registered and periodic so the dispatcher tracks it, then retry","Check that the periodic dispatcher is enabled on the leader","Wait for the leader to restore tracked periodic jobs after an election"],"exampleFix":"// before\njob, _ := client.Jobs().Info(\"my-job\") // job may not exist/periodic\ndispatcher.ForceEval(\"default\", *job.ID)\n// after\njob, _, err := client.Jobs().Info(\"my-job\")\nif err == nil && job != nil && job.IsPeriodic() {\n    _, err = dispatcher.ForceEval(*job.Namespace, *job.ID)\n}","handlingStrategy":"validation","validationCode":"// Go: confirm the job is periodic and exists before ForceEval\njob, _, err := client.Jobs().Info(jobID, &api.QueryOptions{Namespace: ns})\nif err != nil || job == nil { return fmt.Errorf(\"job %q not found\", jobID) }\nif job.Periodic == nil { return fmt.Errorf(\"job %q is not periodic\", jobID) }","typeGuard":null,"tryCatchPattern":"// Go\nif _, err := d.ForceEval(ns, jobID); err != nil {\n    if strings.Contains(err.Error(), \"non-tracked job\") {\n        return fmt.Errorf(\"job %s/%s is not a tracked periodic job\", ns, jobID)\n    }\n}","preventionTips":["List tracked periodic jobs (nomad job list) before forcing","Always pass an explicit namespace","Refresh the job ID from the API rather than hardcoding"],"tags":["nomad","periodic-jobs","not-found"],"backgroundTag":"entity-not-found","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}