{"record":{"id":"b24804290d964e08","repo":"coleam00/Archon","slug":"owner-returned-an-invalid-response","errorCode":null,"errorMessage":"owner returned an invalid response","messagePattern":"owner returned an invalid response","errorType":"exception","errorClass":"DetachedRunOwnerUnavailableError","httpStatus":null,"severity":"error","filePath":"packages/cli/src/utils/detached-run-control.ts","lineNumber":303,"sourceCode":"              resolve();\n            })\n          );\n        }\n        if (process.platform !== 'win32') rmSync(path, { force: true });\n        releaseOwnerLock(lockPath, lockFd);\n      })();\n      return closePromise;\n    },\n    isStopRequested: (): boolean => stopSockets.size > 0,\n  };\n}\n\nfunction parseOwnerResponse(runId: string, raw: string): number {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(raw);\n  } catch {\n    throw new DetachedRunOwnerUnavailableError(runId, 'owner returned an invalid response');\n  }\n  if (\n    typeof parsed !== 'object' ||\n    parsed === null ||\n    !('pid' in parsed) ||\n    typeof parsed.pid !== 'number' ||\n    !Number.isInteger(parsed.pid) ||\n    parsed.pid <= 0\n  ) {\n    throw new DetachedRunOwnerUnavailableError(runId, 'owner returned an invalid PID');\n  }\n  return parsed.pid;\n}\n\n/** Ask the live exact-run owner for an opaque termination lease. */\nexport function requestDetachedRunStop(runId: string): Promise<DetachedRunStopTarget> {\n  const path = detachedRunControlPath(runId);\n  return new Promise((resolve, reject) => {","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/cli/src/utils/detached-run-control.ts#L285-L321","documentation":"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.","triggerScenarios":"The pid getter connects to the control endpoint, receives bytes, but JSON.parse(raw) throws.","commonSituations":"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.","solutions":["Identify what owns the endpoint (the lock file / ps output) and confirm it is an Archon process of a compatible version.","Stop the mismatched owner and restart the run so a matching version serves the socket.","Upgrade or align Archon versions across the machines/shells involved so the control protocol matches."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"function looksLikeOwnerPayload(raw: string): boolean {\n  try { const o = JSON.parse(raw); return typeof o === 'object' && o !== null && 'pid' in o; }\n  catch { return false; }\n}","typeGuard":"function isOwnerPayload(v: unknown): v is { pid: number } {\n  return typeof v === 'object' && v !== null && 'pid' in v && typeof (v as { pid: unknown }).pid === 'number';\n}","tryCatchPattern":"try {\n  const pid = await getDetachedRunOwnerPid(runId);\n} catch (err) {\n  if (err instanceof DetachedRunOwnerUnavailableError && err.reason === 'owner returned an invalid response') {\n    console.error('Endpoint peer is not a compatible Archon owner; stop it and restart the run.');\n  } else throw err;\n}","preventionTips":["Keep the CLI and the detached owner on the same Archon version.","Do not bind unrelated processes to the archon control socket path.","Treat DetachedRunOwnerUnavailableError.reason as the discriminating field for handling."],"tags":["ipc","protocol","json","detached-run"],"backgroundTag":"invalid-response-payload","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}