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
- Close the other running Codewhale session holding the lock, then retry
- Set CODEWHALE_RUNTIME_DIR to a different directory for the second session
- 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
- Unique CODEWHALE_RUNTIME_DIR per session
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
- Another pet recorder is using this output.
- for
- Runtime turn operation is already being claimed; retry
- telemetry privacy lock is held
- The pet recorder lock was replaced; existing files were…
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)