Hmbown/CodeWhale · error

This runtime is already active in another process. Close…

Error message

This runtime is already active in another process. Close the other Codewhale session and try again, or set CODEWHALE_RUNTIME_DIR to a different directory.

What it means

The Runtime takes an exclusive OS file lock (the process owner lock) to guarantee a single active Codewhale runtime per runtime directory. try_lock_exclusive is retried for ~25ms; if the lock is still contended, it bails with RUNTIME_PROCESS_OWNER_LOCK_HELD. This means another live process owns the same CODEWHALE_RUNTIME_DIR.

Solutions

  1. Close the other running Codewhale session holding the lock, then retry
  2. Set CODEWHALE_RUNTIME_DIR to a different directory for the second session
  3. Find and terminate the stale owner process (inspect the lock file's owner PID), or remove the stale lock file if the owner is confirmed dead

Example fix

// before
CODEWHALE_RUNTIME_DIR=~/.codewhale/runtime codewhale tui  # conflicts with running session
// after
CODEWHALE_RUNTIME_DIR=~/.codewhale/runtime-work codewhale tui
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: Starting a second Codewhale session pointed at the same runtime directory while a previous session is still running (or its lock file was left behind by a hung process); launching the CLI and TUI simultaneously on the same CODEWHALE_RUNTIME_DIR.

Common situations: Two terminal tabs running Codewhale in the same project; a crashed session whose lock was never released; CI jobs sharing a HOME/runtime dir; container without per-job runtime dirs.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/eeaeb452495e1ab0. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/runtime_threads.rs:4204

            options.create(true).truncate(false).read(true).write(true);
        })?;
        #[cfg(unix)]
        {
            use std::os::unix::fs::PermissionsExt as _;
            file.set_permissions(fs::Permissions::from_mode(0o600))
                .context("Failed to protect Runtime process owner lock")?;
        }
        // Same-process drop-then-reopen can observe WouldBlock for a brief
        // window while the previous fd is still closing — the same close-
        // release race #5735 hit on the Runtime Chat scope lock. Retry only
        // that contention; a lock that stays held still belongs to its owner.
        let deadline = Instant::now() + Duration::from_millis(25);
        loop {
            match Self::try_lock_exclusive(&file) {
                Ok(()) => break,
                Err(error) if Self::is_contention(&error) => {
                    if Instant::now() >= deadline {
                        bail!("{RUNTIME_PROCESS_OWNER_LOCK_HELD}");
                    }
                    std::thread::yield_now();
                    std::thread::sleep(Duration::from_millis(1));
                }
                Err(error) => {
                    return Err(error).context("Failed to acquire Runtime process owner lock");
                }
            }
        }
        Ok(Self { _file: file })
    }

    fn is_contention(error: &std::io::Error) -> bool {
        error.kind() == std::io::ErrorKind::WouldBlock
            || matches!(error.raw_os_error(), Some(32 | 33))
    }

    fn try_lock_exclusive(file: &File) -> std::io::Result<()> {

View on GitHub (pinned to 433685b202)