{"record":{"id":"7194c7f60aea2b4d","repo":"hashicorp/nomad","slug":"launch-not-found","errorCode":null,"errorMessage":"launch not found","messagePattern":"launch not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store.go","lineNumber":3391,"sourceCode":"\tdefer txn.Abort()\n\n\terr := s.DeletePeriodicLaunchTxn(index, namespace, jobID, txn)\n\tif err == nil {\n\t\treturn txn.Commit()\n\t}\n\treturn err\n}\n\n// DeletePeriodicLaunchTxn is used to delete the periodic launch, like DeletePeriodicLaunch\n// but in a transaction.  Useful for when making multiple modifications atomically\nfunc (s *StateStore) DeletePeriodicLaunchTxn(index uint64, namespace, jobID string, txn Txn) error {\n\t// Lookup the launch\n\texisting, err := txn.First(\"periodic_launch\", \"id\", namespace, jobID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"launch lookup failed: %v\", err)\n\t}\n\tif existing == nil {\n\t\treturn fmt.Errorf(\"launch not found\")\n\t}\n\n\t// Delete the launch\n\tif err := txn.Delete(\"periodic_launch\", existing); err != nil {\n\t\treturn fmt.Errorf(\"launch delete failed: %v\", err)\n\t}\n\tif err := txn.Insert(\"index\", &IndexEntry{\"periodic_launch\", index}); err != nil {\n\t\treturn fmt.Errorf(\"index update failed: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// PeriodicLaunchByID is used to lookup a periodic launch by the periodic job\n// ID.\nfunc (s *StateStore) PeriodicLaunchByID(ws memdb.WatchSet, namespace, id string) (*structs.PeriodicLaunch, error) {\n\ttxn := s.db.ReadTxn()\n","sourceCodeStart":3373,"sourceCodeEnd":3409,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store.go#L3373-L3409","documentation":"Returned by StateStore.DeletePeriodicLaunchTxn when no PeriodicLaunch record exists for the given (namespace, jobID). The launch bookkeeping (last launched time for a periodic job) is absent, so there is nothing to delete and the caller's intent is invalid.","triggerScenarios":"Calling DeletePeriodicLaunch(index, namespace, jobID) for a job ID that never had UpsertPeriodicLaunch called, or for a job that was already deleted (or whose launch was already removed), e.g. deleting a periodic job twice.","commonSituations":"Deregistering a periodic job whose launch entry was already cleaned up by a prior delete or job purge; stale job IDs from an older namespace; calling delete with namespace/jobID swapped.","solutions":["Treat this as an idempotency signal: if the job is already gone, log and return success instead of erroring","Verify the namespace and job ID match the registered periodic job (use job list / job inspect)","Ensure the job was actually registered as periodic before deleting its launch record","Check for duplicate delete calls in your automation (e.g. retries after a successful delete)"],"exampleFix":"// before\nif err := state.DeletePeriodicLaunch(100, \"default\", \"my-periodic\"); err != nil {\n\treturn err\n}\n// after\nif err := state.DeletePeriodicLaunch(100, \"default\", \"my-periodic\"); err != nil {\n\tif strings.Contains(err.Error(), \"launch not found\") {\n\t\treturn nil // already deleted; idempotent\n\t}\n\treturn err\n}","handlingStrategy":"validation","validationCode":"launch, err := state.PeriodicLaunchByID(ws, namespace, jobID)\nif err != nil { return err }\nif launch == nil {\n\t// already deleted or never launched: skip delete\n\treturn nil\n}","typeGuard":"if l, ok := existing.(*structs.PeriodicLaunch); !ok || l == nil { return nil }","tryCatchPattern":"if err := state.DeletePeriodicLaunch(idx, ns, jobID); err != nil {\n\tif strings.Contains(err.Error(), \"launch not found\") {\n\t\treturn nil // idempotent success\n\t}\n\treturn err\n}","preventionTips":["Check existence with PeriodicLaunchByID before delete","Make delete flows idempotent (treat not-found as success)","Guard against double deletes from retries in automation"],"tags":["nomad","state-store","periodic-job","not-found"],"backgroundTag":"resource-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"}