{"record":{"id":"718c2183c7f27568","repo":"hashicorp/nomad","slug":"launch-delete-failed-v","errorCode":null,"errorMessage":"launch delete failed: %v","messagePattern":"launch delete failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store.go","lineNumber":3396,"sourceCode":"\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\n\twatchCh, existing, err := txn.FirstWatch(\"periodic_launch\", \"id\", namespace, id)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"periodic launch lookup failed: %v\", err)\n\t}\n","sourceCodeStart":3378,"sourceCodeEnd":3414,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store.go#L3378-L3414","documentation":"Returned by StateStore.DeletePeriodicLaunchTxn when txn.Delete on the 'periodic_launch' table fails after the record was found. The launch exists but memdb refuses the delete, aborting the transaction (it will not be committed by the wrapper).","triggerScenarios":"Calling DeletePeriodicLaunch/DeletePeriodicLaunchTxn when the memdb Delete of the existing PeriodicLaunch object errors — e.g. object/table mismatch inside memdb or an invalid txn state.","commonSituations":"Mixed-version agents writing incompatible objects into the state store; in-memory DB corruption; bespoke code passing objects of the wrong type into a shared txn.","solutions":["Check the wrapped inner memdb error in the message for the exact cause","Restart nomad servers so in-memory state is rebuilt from raft snapshots","Ensure all writers use the canonical state store apply path (no custom txns against s.db)","If it follows an upgrade, verify all servers run the same nomad version"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Confirm the launch exists and is the expected type first\nraw, err := txn.First(\"periodic_launch\", \"id\", ns, jobID)\nif err != nil { return err }\nif _, ok := raw.(*structs.PeriodicLaunch); !ok { return fmt.Errorf(\"unexpected row type\") }","typeGuard":"if l, ok := raw.(*structs.PeriodicLaunch); ok { /* use l */ }","tryCatchPattern":"if err := state.DeletePeriodicLaunch(idx, ns, jobID); err != nil {\n\tif strings.Contains(err.Error(), \"launch delete failed\") {\n\t\t// log wrapped memdb cause; plan a server restart if persistent\n\t}\n\treturn err\n}","preventionTips":["Never write directly to memdb outside the apply loop","Keep agent versions aligned to avoid schema mismatches","Surface the inner error in logs for diagnosis"],"tags":["nomad","memdb","state-store","delete"],"backgroundTag":"memdb-delete-failed","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"}