{"record":{"id":"06d529544f9f9851","repo":"dbt-labs/dbt-core","slug":"inconsistent-state-in-unpark","errorCode":null,"errorMessage":"inconsistent state in unpark","messagePattern":"inconsistent state in unpark","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-runtime/src/park.rs","lineNumber":177,"sourceCode":"\n        match self.state.swap(EMPTY, SeqCst) {\n            NOTIFIED => {} // got a notification, hurray!\n            PARKED => {}   // no notification, alas\n            n => panic!(\"inconsistent park_timeout state: {n}\"),\n        }\n    }\n\n    fn unpark(&self) {\n        // To ensure the unparked thread will observe any writes we made before\n        // this call, we must perform a release operation that `park` can\n        // synchronize with. To do that we must write `NOTIFIED` even if `state`\n        // is already `NOTIFIED`. That is why this must be a swap rather than a\n        // compare-and-swap that returns if it reads `NOTIFIED` on failure.\n        match self.state.swap(NOTIFIED, SeqCst) {\n            EMPTY => return,    // no one was waiting\n            NOTIFIED => return, // already unparked\n            PARKED => {}        // gotta go wake someone up\n            _ => panic!(\"inconsistent state in unpark\"),\n        }\n\n        // There is a period between when the parked thread sets `state` to\n        // `PARKED` (or last checked `state` in the case of a spurious wake\n        // up) and when it actually waits on `cvar`. If we were to notify\n        // during this period it would be ignored and then when the parked\n        // thread went to sleep it would never wake up. Fortunately, it has\n        // `lock` locked at this stage so we can acquire `lock` to wait until\n        // it is ready to receive the notification.\n        //\n        // Releasing `lock` before the call to `notify_one` means that when the\n        // parked thread wakes it doesn't get woken only to have to wait for us\n        // to release `lock`.\n        drop(self.mutex.lock().unwrap());\n\n        self.condvar.notify_one();\n    }\n}","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-runtime/src/park.rs#L159-L195","documentation":"unpark sets the parker state to NOTIFIED via an atomic swap and expects one of the three legal values. Any other value means the state machine was corrupted, so the library panics instead of attempting to wake a thread in an undefined state. Like error 20, this is an internal invariant guard protecting the thread-parking synchronization protocol.","triggerScenarios":"unpark's swap(NOTIFIED, SeqCst) returns a value not in {EMPTY, NOTIFIED, PARKED} — only possible via out-of-band writes to the parker's state atomic (unsafe aliasing, corruption).","commonSituations":"Not hit in normal usage; appears when debugging concurrent runtimes, fuzzing unsafe code paths, or chasing memory corruption caused elsewhere in the process.","solutions":["File a bug with dbt-runtime maintainers including the reproducer; a non-enum value here signals state-machine corruption","Audit any unsafe code in your workspace that could write to the runtime's internal parker state","Upgrade dbt-runtime to the latest release to pick up any fixes","Run the workload under ThreadSanitizer or Miri in tests to locate the corrupting write"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// unpark is internal; wrap if exposing custom scheduling\nlet result = std::panic::catch_unwind(|| parker.unpark());\nif result.is_err() { /* treat as corruption; fail fast with diagnostics */ }","preventionTips":["Never alias or mutate parker internals from unsafe code","Run under sanitizers when touching concurrency primitives","Upgrade dbt-runtime before debugging further","Treat every occurrence as a library bug and report it"],"tags":["rust","concurrency","panic","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}