Hmbown/CodeWhale · error · anyhow::Error
lane `{}` was stopped before inline start completed
Error message
lane `{}` was stopped before inline start completed What it means
InlineRuntime::start applies the worktree and appends the lane_started event, then calls registry.mark_running_if_pending(record). A false return means a concurrent stop already moved the lane out of Pending, so the start aborts before spawning the child process — no orphan process is left behind, and the caller gets this explicit race signal.
Source
Thrown at crates/lane/src/runtime.rs:969
registry: &LaneRegistry,
record: &mut LaneRecord,
spec: &LaneStartSpec,
) -> Result<()> {
if spec.command.is_empty() {
bail!("inline runtime requires a non-empty command");
}
let cwd = apply_worktree(record, spec)?;
append_log_event(
&record.log_path,
serde_json::json!({
"type": "lane_started",
"lane_id": record.id,
"runtime": "inline",
"command": spec.command,
}),
)?;
if !registry.mark_running_if_pending(record)? {
bail!(
"lane `{}` was stopped before inline start completed",
record.id
);
}
let mut cmd = Command::new(&spec.command[0]);
if spec.command.len() > 1 {
cmd.args(&spec.command[1..]);
}
if let Some(cwd) = cwd.as_ref() {
cmd.current_dir(cwd);
}
cmd.envs(spec.environment.iter().map(|(key, value)| (key, value)));
cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
let mut child = match cmd.spawn() {
Ok(child) => child,
Err(err) => {
append_log_event(View on GitHub (pinned to 0c42157ee5)
Solutions
- Refetch the lane record and treat it as stopped (it is); decide explicitly whether to start again
- Await start completion before issuing stop in calling code
- Coordinate concurrent lifecycle operations per lane (locks or fences)
Defensive patterns
Strategy: try-catch
Try / catch
match runtime.start(®istry, &mut record, &spec) {
Ok(()) => { /* child spawned */ }
Err(err) if err.to_string().contains("stopped before inline start completed") => {
// Race lost to a concurrent stop; no child was spawned, worktree may remain per caller.
let fresh = registry.get(&record.id)?;
assert_eq!(fresh.status, LaneStatus::Stopped);
}
Err(err) => return Err(err),
} Prevention
- Wait for start to finish before issuing stop on the same lane
- Route all lifecycle operations for one lane through a single owner or mutex
When it happens
Trigger: An inline lane start racing a concurrent stop on the same lane id: the stop's terminal transition commits between the lane_started log event and the Pending->Running compare-and-set.
Common situations: UIs letting users cancel while a lane is launching; automation that stops on a timeout fired right after start; concurrent managers operating the same lane registry.
Related errors
- lane `{}` was stopped before tmux launch
- terminal lane transition requires a terminal status
- lane `{}` was stopped before tmux dry-run start completed
- inline runtime requires a non-empty command
- inline lane `{}` cannot be stopped safely from another proce
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/97c84dd5ad96ef35.
Report an issue: GitHub.