astral-sh/ruff · critical

tried to set QoS of thread which has opted out of QoS

Error message

tried to set QoS of thread which has opted out of QoS (os error {errno})

What it means

On macOS, ty's scheduler sets the current thread's QoS class via `pthread_set_qos_class_self_np`. If the thread has opted out of the QoS system (e.g. a prior call to `pthread_setschedparam`), the call fails with EPERM, and ty panics because its design invariant is that it only ever uses QoS-compatible scheduling APIs. This is a macOS-only, internal-invariant panic.

Solutions

  1. Run the ty server on threads that have not had their scheduling configured via pthread_setschedparam or similar APIs.
  2. Remove or defer manual thread-priority calls in the embedding code before starting ty's scheduler.
  3. Use fresh default-priority threads for the server's worker pool.

Example fix

// before: host code sets a fixed priority before starting ty
pthread_setschedparam(thread, SCHED_FIFO, &param);
ty_server::start(...);
// after: start ty on an untouched thread, then customize elsewhere
ty_server::start(...);
Defensive patterns

Strategy: try-catch

Validate before calling

// macOS: ensure the host thread has not opted out of QoS before hosting ty
let is_qos_compatible = std::env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("macos")
    || !manual_scheduling_used;
if !is_qos_compatible { /* run ty on a fresh default-priority thread */ }

Try / catch

// The API panics, so guard by construction; catch at the thread boundary:
std::panic::catch_unwind(|| ty_server::run_on_current_thread())
    .map_err(|_| "thread opted out of QoS; re-run on a clean thread")

Prevention

When it happens

Trigger: Running ty's LSP server on macOS inside a thread that previously called `pthread_setschedparam` or another manual scheduling API, so `set_current_thread_qos_class` receives errno EPERM.

Common situations: Embedding ty's server into another application that manages its own thread priorities; running within runtimes or wrappers that adjust thread scheduling; macOS-only regressions when hosting the server in foreign threads.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/90904f06b816b3d6. Report an issue: GitHub.

Appendix: source

Thrown at crates/ty_server/src/server/schedule/thread/priority.rs:204

        #[expect(unsafe_code)]
        let code = unsafe { libc::pthread_set_qos_class_self_np(c, 0) };

        if code == 0 {
            return;
        }

        #[expect(unsafe_code)]
        let errno = unsafe { *libc::__error() };

        match errno {
            libc::EPERM => {
                // This thread has been excluded from the QoS system
                // due to a previous call to a function such as `pthread_setschedparam`
                // which is incompatible with QoS.
                //
                // Panic instead of returning an error
                // to maintain the invariant that we only use QoS APIs.
                panic!("tried to set QoS of thread which has opted out of QoS (os error {errno})")
            }

            libc::EINVAL => {
                // This is returned if we pass something other than a qos_class_t
                // to `pthread_set_qos_class_self_np`.
                //
                // This is impossible, so again panic.
                unreachable!(
                    "invalid qos_class_t value was passed to pthread_set_qos_class_self_np"
                )
            }

            _ => {
                // `pthread_set_qos_class_self_np`’s documentation
                // does not mention any other errors.
                unreachable!("`pthread_set_qos_class_self_np` returned unexpected error {errno}")
            }
        }

View on GitHub (pinned to 26f38c119c)