{"record":{"id":"c8e3c10ab10fb1be","repo":"paperclipai/paperclip","slug":"createos-process-exit-status-is-missing","errorCode":null,"errorMessage":"CreateOS process exit status is missing.","messagePattern":"CreateOS process exit status is missing\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/sandbox-providers/createos/src/execute.ts","lineNumber":169,"sourceCode":"          if (event.type === \"heartbeat\") continue;\n          if (event.type === \"data\") {\n            const seq = event.seq;\n            if (typeof seq !== \"number\" || !Number.isSafeInteger(seq) || seq < 1) throw new Error(\"CreateOS process sequence is invalid.\");\n            if (seq <= cursor) continue;\n            if (seq !== cursor + 1) throw new Error(\"CreateOS process output has a sequence gap.\");\n            if ((event.stream !== \"stdout\" && event.stream !== \"stderr\") ||\n                typeof event.data_base64 !== \"string\" ||\n                !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(event.data_base64)) {\n              throw new Error(\"CreateOS process output is invalid.\");\n            }\n            output.write(event.stream, Buffer.from(event.data_base64, \"base64\"));\n            cursor = seq;\n          } else if (event.type === \"exit\") {\n            const exitCode = event.exit_code;\n            const exitSignal = event.signal;\n            if (!(typeof exitCode === \"number\" && Number.isInteger(exitCode)) &&\n                !(typeof exitSignal === \"string\" && /^SIG[A-Z0-9]+$/.test(exitSignal))) {\n              throw new Error(\"CreateOS process exit status is missing.\");\n            }\n            completed = true;\n            output.finish();\n            return {\n              exitCode: typeof exitCode === \"number\" ? exitCode : null,\n              signal: typeof exitSignal === \"string\" ? exitSignal : null,\n              timedOut: false, stdout: output.stdout, stderr: output.stderr,\n              metadata: { processId, outputTruncated: output.truncated },\n            };\n          } else if (event.type === \"error\") {\n            throw new Error(event.error === \"output_offset_expired\"\n              ? \"CreateOS process output was evicted before it could be read.\"\n              : \"CreateOS process stream reported an error.\");\n          } else {\n            throw new Error(\"CreateOS returned an unknown process event.\");\n          }\n        }\n      } catch (error) {","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/plugins/sandbox-providers/createos/src/execute.ts#L151-L187","documentation":"The process stream delivered an `exit` event that contained neither a valid integer `exit_code` nor a `signal` string matching /^SIG[A-Z0-9]+$/. Without one of these the completion status is unknowable, so the plugin refuses to fabricate a result.","triggerScenarios":"CreateOS emits {\"type\":\"exit\"} with missing/null exit_code and signal, a float exit_code, or a malformed signal name; a protocol change renames these fields.","commonSituations":"CreateOS version upgrade renaming exit fields; server crash while finalizing process exit; proxy stripping unknown fields from event JSON.","solutions":["Capture the raw exit frame and diff it against the documented exit-event schema.","Pin the CreateOS service version to one matching the plugin's expected protocol.","Check for intermediaries rewriting or filtering event fields.","Re-run the command; note cleanup will terminate the unfinished process tree, so a rerun is safe."],"exampleFix":"// before\n{ \"type\": \"exit\", \"status\": \"done\" }\n// after\n{ \"type\": \"exit\", \"exit_code\": 0 }   // or { \"type\": \"exit\", \"signal\": \"SIGKILL\" }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function hasExitStatus(e: Record<string, unknown>): boolean {\n  const code = e.exit_code, sig = e.signal;\n  return (typeof code === \"number\" && Number.isInteger(code))\n    || (typeof sig === \"string\" && /^SIG[A-Z0-9]+$/.test(sig));\n}","tryCatchPattern":"try { const r = await execute(client, params, signal); }\ncatch (e) {\n  if (e instanceof Error && e.message === \"CreateOS process exit status is missing.\") {\n    // exit frame malformed: re-run; cleanup has already terminated the tree\n  } else throw e;\n}","preventionTips":["Keep exit-event field names (exit_code/signal) synchronized across service versions.","Block intermediaries that strip or rename event fields.","Validate the exit-event schema in integration tests.","Re-run commands rather than guessing an exit status."],"tags":["protocol","exit-status","streaming"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}