Hmbown/CodeWhale · error

lane ` ` is and has no active attach target

Error message

lane `{lane_id}` is {} and has no active attach target

What it means

When resolving the attach command for a lane, the backend returned no attach target (`attach_command` returned None). The code then distinguishes two cases: if the lane's status is not active, it fails with 'lane `<id>` is <status> and has no active attach target'. This tells the user the lane is in a non-runnable state (stopped, finished, failed) so there is nothing to attach to.

Solutions

  1. Check the lane status (`codewhale lane --status` / `--show <id>`); if it finished, start a new lane instead of attaching.
  2. If the lane should be running, restart/resume it (lane control operation) so its status becomes active, then attach.
  3. Investigate why the lane is inactive (logs, reconcile output) if it was expected to be running.

Example fix

// before
codewhale lane attach old-lane-1   # status: finished
// after
codewhale lane new ...             # start a fresh lane, then attach
Defensive patterns

Strategy: validation

Validate before calling

const lane = await showLane(id);
if (!ACTIVE_STATUSES.includes(lane.status)) throw new Error(`lane ${id} is ${lane.status}; start a new lane instead of attaching`);

Type guard

function isAttachable(lane) { return typeof lane.status === 'string' && ['running','active'].includes(lane.status); }

Prevention

When it happens

Trigger: `codewhale lane --attach <lane_id>` (or equivalent) on a lane whose `lane.status.is_active()` is false after `backend.reconcile` — e.g. an exited, failed, or never-started lane.

Common situations: Attaching to a lane after its agent process finished; a lane that failed at startup; reusing an old lane id from a previous session; environment where reconcile marks the lane inactive (crashed tmux session).

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/69981500efd2f491. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/lib.rs:950

            run_lane_control(ControlOperation::LaneStatus, Some(&lane_id), json)
        }
        LaneCommand::Interrupt { lane_id, json } => {
            run_lane_control(ControlOperation::LaneInterrupt, Some(&lane_id), json)
        }
        LaneCommand::Restart { lane_id, json } => {
            run_lane_control(ControlOperation::LaneRestart, Some(&lane_id), json)
        }
        LaneCommand::Resume { lane_id, json } => {
            run_lane_control(ControlOperation::LaneResume, Some(&lane_id), json)
        }
        LaneCommand::Attach { lane_id, print } => {
            let reg = LaneRegistry::open_default()?;
            let mut lane = reg.load(&lane_id)?;
            let backend = backend_for(&lane);
            backend.reconcile(&reg, &mut lane)?;
            let Some(attach) = backend.attach_command(&lane) else {
                if !lane.status.is_active() {
                    bail!(
                        "lane `{lane_id}` is {} and has no active attach target",
                        lane.status.as_str()
                    );
                }
                bail!(
                    "lane `{lane_id}` runtime `{}` has no attach target",
                    lane.runtime.as_str()
                );
            };
            if print {
                println!("{attach}");
                return Ok(());
            }
            if let Some(session) = lane.tmux_session.as_deref() {
                let socket = lane
                    .tmux_socket
                    .as_deref()
                    .context("tmux lane is missing its pinned server socket")?;

View on GitHub (pinned to 73e0f67d83)