{"record":{"id":"c67c1d03ef893442","repo":"dbt-labs/dbt-core","slug":"inconsistent-park-timeout-state-actual-actual","errorCode":null,"errorMessage":"inconsistent park_timeout state; actual = {actual}","messagePattern":"inconsistent park_timeout state; actual = (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-runtime/src/park.rs","lineNumber":151,"sourceCode":"            return;\n        }\n\n        if dur == Duration::from_millis(0) {\n            return;\n        }\n\n        let m = self.mutex.lock().unwrap();\n\n        match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {\n            Ok(_) => {}\n            Err(NOTIFIED) => {\n                // 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","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-runtime/src/park.rs#L133-L169","documentation":"The timed variant of the custom park: park_timeout() swaps the atomic state to EMPTY and requires the previous value to be NOTIFIED (a pending unpark token) or EMPTY (no token, spurious path handled above). Any other observed value means the park state machine is inconsistent, so it panics with the unexpected state.","triggerScenarios":"park_timeout() observing a corrupted or unexpected atomic state — concurrent unpark racing with the timeout path, a double-unpark that left state outside the EMPTY/NOTIFIED domain, custom state values introduced by modifications, or a memory-ordering bug in the park implementation.","commonSituations":"Timed blocking-pool waits under heavy timeout churn; races between a timeout firing and an unpark token being consumed; code paths where park() and park_timeout() interleave on the same Parker with custom state values.","solutions":["Treat as a runtime bug: capture `actual` and reproduce; this panic is not actionable from caller code.","Review park/unpark/park_timeout transitions to guarantee state is only ever EMPTY or NOTIFIED.","Ensure unpark consumes exactly one token and cannot set state while park_timeout is mid-transition.","Downgrade or patch to a runtime version without the park race; add stress tests with timeouts under contention."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// internal invariant panic: guard the runtime process, not the call\nlet result = std::panic::catch_unwind(AssertUnwindSafe(|| timed_wait(dur)));\nif result.is_err() {\n    eprintln!(\"park_timeout state panic; resetting parker and retrying\");\n    reset_parker_and_retry(dur);\n}","preventionTips":["Avoid mixing custom state values into the Parker's atomic; only EMPTY and NOTIFIED are valid.","Ensure unpark cannot interleave with park_timeout's swap-to-EMPTY window.","Exercise timed waits under contention in CI stress tests to catch races before production.","Report reproducible failures upstream with the `actual` value from the panic message."],"tags":["rust","runtime","panic","concurrency","park-timeout"],"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"}