coleam00/Archon · error · DetachedRunOwnerUnavailableError

owner returned an invalid response

Error message

owner returned an invalid response

What it means

parseOwnerResponse() asks the live run owner for its pid and expects JSON of the shape {"pid": <positive integer>}. If the raw response is not valid JSON, it throws DetachedRunOwnerUnavailableError with reason 'owner returned an invalid response', meaning the endpoint answered but with a malformed payload. This indicates the peer on the socket is not behaving like the current Archon control protocol.

Source

Thrown at packages/cli/src/utils/detached-run-control.ts:303

              resolve();
            })
          );
        }
        if (process.platform !== 'win32') rmSync(path, { force: true });
        releaseOwnerLock(lockPath, lockFd);
      })();
      return closePromise;
    },
    isStopRequested: (): boolean => stopSockets.size > 0,
  };
}

function parseOwnerResponse(runId: string, raw: string): number {
  let parsed: unknown;
  try {
    parsed = JSON.parse(raw);
  } catch {
    throw new DetachedRunOwnerUnavailableError(runId, 'owner returned an invalid response');
  }
  if (
    typeof parsed !== 'object' ||
    parsed === null ||
    !('pid' in parsed) ||
    typeof parsed.pid !== 'number' ||
    !Number.isInteger(parsed.pid) ||
    parsed.pid <= 0
  ) {
    throw new DetachedRunOwnerUnavailableError(runId, 'owner returned an invalid PID');
  }
  return parsed.pid;
}

/** Ask the live exact-run owner for an opaque termination lease. */
export function requestDetachedRunStop(runId: string): Promise<DetachedRunStopTarget> {
  const path = detachedRunControlPath(runId);
  return new Promise((resolve, reject) => {

View on GitHub (pinned to 0773b97458)

Solutions

  1. Identify what owns the endpoint (the lock file / ps output) and confirm it is an Archon process of a compatible version.
  2. Stop the mismatched owner and restart the run so a matching version serves the socket.
  3. Upgrade or align Archon versions across the machines/shells involved so the control protocol matches.
Defensive patterns

Strategy: type-guard

Validate before calling

function looksLikeOwnerPayload(raw: string): boolean {
  try { const o = JSON.parse(raw); return typeof o === 'object' && o !== null && 'pid' in o; }
  catch { return false; }
}

Type guard

function isOwnerPayload(v: unknown): v is { pid: number } {
  return typeof v === 'object' && v !== null && 'pid' in v && typeof (v as { pid: unknown }).pid === 'number';
}

Try / catch

try {
  const pid = await getDetachedRunOwnerPid(runId);
} catch (err) {
  if (err instanceof DetachedRunOwnerUnavailableError && err.reason === 'owner returned an invalid response') {
    console.error('Endpoint peer is not a compatible Archon owner; stop it and restart the run.');
  } else throw err;
}

Prevention

When it happens

Trigger: The pid getter connects to the control endpoint, receives bytes, but JSON.parse(raw) throws.

Common situations: A different (older/newer) Archon version owns the socket and replies in a different format; an unrelated process bound to the socket path; truncated or binary garbage from a crashed half-open connection.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/b24804290d964e08. Report an issue: GitHub.