paperclipai/paperclip · warning

SSH env-lab fixture state exists, but the process is not run

Error message

SSH env-lab fixture state exists, but the process is not running.

What it means

env-lab doctor found a fixture state.json (written by a previous `paperclipai env-lab up`) at the printed State path, but the recorded sshd pid is no longer a live process (readSshEnvLabFixtureStatus checks the pid against the expected sshd command line). The state is stale — the fixture is not currently usable.

Source

Thrown at cli/src/commands/env-lab.ts:205

  if (opts.json) {
    printJson(status);
    return;
  }

  if (status.ssh.supported) {
    p.log.success("SSH fixture prerequisites are installed.");
  } else {
    p.log.warn(`SSH fixture prerequisites are incomplete: ${status.ssh.reason ?? "unknown reason"}`);
  }

  if (status.ssh.state && status.ssh.running) {
    p.log.success("SSH env-lab fixture is running.");
    summarizeFixture(status.ssh.state);
    p.log.message(`Private key: ${pc.dim(status.ssh.state.clientPrivateKeyPath)}`);
    p.log.message(`Known hosts: ${pc.dim(status.ssh.state.knownHostsPath)}`);
  } else if (status.ssh.state) {
    p.log.warn("SSH env-lab fixture state exists, but the process is not running.");
    p.log.message(`State: ${pc.dim(status.statePath)}`);
  } else {
    p.log.info("SSH env-lab fixture is not running.");
    p.log.message(`State: ${pc.dim(status.statePath)}`);
  }

  // The cleanup hint runs the same CLI that prints it, so it stops the correct
  // version. The bundled build runs `dist/index.js`; a source checkout runs
  // `src/index.ts` through the checked-out tsx runner. The hint uses absolute
  // paths, so it works from any working directory. It passes an inert `argv`
  // value, so no shell reads the argument. See `doc/CLI.md`, "safe invocation".
  //
  // The doctor diagnoses the instance that `resolvePaperclipInstanceId` selects
  // from `opts.instance` or the `PAPERCLIP_INSTANCE_ID` environment variable.
  // The hint pins that resolved instance, so a contributor who pastes the hint
  // in a shell without `PAPERCLIP_INSTANCE_ID` stops the diagnosed fixture, not
  // the default instance.
  const cleanupInstance = resolvePaperclipInstanceId(opts.instance);

View on GitHub (pinned to 120ae5428f)

Solutions

  1. Run `paperclipai env-lab up` to start a fresh fixture (it rewrites the state).
  2. Or run `paperclipai env-lab down` to clear the stale state if you no longer need the fixture.
  3. If both complain, delete the printed state.json file under the instance env-lab/ssh-fixture directory and re-run up.
Defensive patterns

Strategy: validation

Validate before calling

const status = await readSshEnvLabFixtureStatus(statePath);
if (status.state && !status.running) {
  await stopSshEnvLabFixture({ statePath }); // clear stale state
  await startSshEnvLabFixture({ statePath }); // or restart fresh
}

Type guard

const isRunningFixture = (s: { state?: unknown; running?: boolean }): s is { state: object; running: true } =>
  Boolean(s.state) && s.running === true;

Prevention

When it happens

Trigger: Machine or container rebooted since `env-lab up`; the sshd fixture process was killed; a new boot reused a different instance root; leftover state file from a crashed session.

Common situations: Restarting a dev machine or docker container that previously started the fixture; OOM killer terminating sshd; switching between Paperclip instances with a stale env-lab dir.

Related errors


AI-assisted analysis of paperclipai/paperclip@120ae5428f (2026-08-18). Data as JSON: /api/errors/03d6af5815a3845f. Report an issue: GitHub.