{"record":{"id":"505034cfa7e1ca3a","repo":"dbt-labs/dbt-core","slug":"inconsistent-park-timeout-state-n","errorCode":null,"errorMessage":"inconsistent park_timeout state: {n}","messagePattern":"inconsistent park_timeout state: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-runtime/src/park.rs","lineNumber":163,"sourceCode":"                // We must read again here, see `park`.\n                let old = self.state.swap(EMPTY, SeqCst);\n                debug_assert_eq!(old, NOTIFIED, \"park state changed unexpectedly\");\n\n                return;\n            }\n            Err(actual) => panic!(\"inconsistent park_timeout state; actual = {actual}\"),\n        }\n\n        // Wait with a timeout, and if we spuriously wake up or otherwise wake up\n        // from a notification, we just want to unconditionally set the state back to\n        // empty, either consuming a notification or un-flagging ourselves as\n        // parked.\n        let (_m, _result) = self.condvar.wait_timeout(m, dur).unwrap();\n\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","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-runtime/src/park.rs#L145-L181","documentation":"This panic is a defensive invariant check in the thread parking primitive used by dbt-runtime. The parker's state machine has exactly three legal values (EMPTY, PARKED, NOTIFIED); after a timed wait, the atomic state is swapped back to EMPTY, and any value other than NOTIFIED or PARKED means the state machine was corrupted, so the library aborts rather than continue in an undefined synchronization state.","triggerScenarios":"park_timeout observes an atomic state value outside the {EMPTY, PARKED, NOTIFIED} domain when re-reading state after condvar.wait_timeout returns — i.e. memory corruption or a misuse of the parker internals writes an out-of-domain value into self.state.","commonSituations":"Practically unreachable for library users; seen only during fuzzing, unsafe-code misuse around the parker, or a bug in dbt-runtime itself. Developers encounter it while debugging concurrency bugs or after low-memory/alien-thread interference in custom runtime extensions.","solutions":["Report the issue to the dbt-runtime maintainers with a minimal reproducer; this indicates a bug in the parker's internal state machine","Check for unsafe code in your project that aliases or writes to the parker's internal state","Update dbt-runtime to the latest version in case the invariant bug is already fixed","Capture the panicking state value ({n} in the message) and add debug assertions around park/unpark call sites in your code"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// park_timeout is an internal primitive; if surfaced, catch panic and report\nlet result = std::panic::catch_unwind(|| parker.park_timeout(dur));\nif result.is_err() { /* log state-machine corruption and file a bug */ }","preventionTips":["Do not write to the parker's internal state from unsafe code","Keep dbt-runtime updated","Run concurrency tests under Miri/ThreadSanitizer","Report any occurrence with a reproducer — it is always a bug"],"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"}