{"record":{"id":"3c3d66e5c258e252","repo":"paperclipai/paperclip","slug":"createos-command-was-cancelled","errorCode":null,"errorMessage":"CreateOS command was cancelled.","messagePattern":"CreateOS command was cancelled\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/plugins/sandbox-providers/createos/src/execute.ts","lineNumber":206,"sourceCode":"        // Network read failures can resume from the last accepted sequence.\n        // Protocol errors must fail closed rather than reconnect past bad data.\n        if (!(error instanceof TypeError) || signal.aborted) throw error;\n      }\n      if (++reconnects > 3) throw new Error(\"CreateOS process stream ended without an exit status.\");\n      await delay(250, undefined, { signal });\n    }\n  } catch (error) {\n    if (creationMayHaveSucceeded && !processId) {\n      throw new CreateosCleanupError(\"CreateOS process creation could not be confirmed; destroy the lease before reusing it.\");\n    }\n    if (signal.aborted && signal.reason?.name === \"TimeoutError\") {\n      output.finish();\n      return {\n        exitCode: null, timedOut: true, stdout: output.stdout, stderr: output.stderr,\n        metadata: { processId, outputTruncated: output.truncated },\n      };\n    }\n    if (signal.aborted) throw new Error(\"CreateOS command was cancelled.\");\n    throw error;\n  } finally {\n    const cleanupSignal = AbortSignal.timeout(client.config.timeoutMs);\n    // Do not hide a cleanup failure: the host must know containment is unproven.\n    try {\n      if (processId && !completed) {\n        try {\n          const termination = await client.json(`${base}/${processId}?grace_ms=1000`, \"DELETE\", undefined, cleanupSignal);\n          if (termination.tree_exited !== true) throw new Error(\"Process tree has not exited.\");\n        }\n        catch (error) { if (!(error instanceof CreateosApiError && error.status === 404)) throw new CreateosCleanupError(\"CreateOS command cleanup failed; process termination is unconfirmed.\"); }\n      }\n    } finally {\n      if (staged && stdinPath) {\n        // /files has no delete verb. /exec supplies a bounded, one-shot removal\n        // after the managed process finishes, without retaining another record.\n        await client.json(`/sandboxes/${id}/exec`, \"POST\", {\n          cmd: \"/bin/rm\", args: [\"-f\", \"--\", stdinPath],","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/packages/plugins/sandbox-providers/createos/src/execute.ts#L188-L224","documentation":"Thrown when the AbortSignal passed to execute() was aborted but the abort was not the configured timeout (which is handled separately by returning a timedOut result). It means the caller explicitly cancelled the CreateOS command. The error is rethrown from the catch block after cleanup bookkeeping.","triggerScenarios":"Caller aborts the signal (AbortController.abort()) while the process runs for a reason other than TimeoutError — e.g. user cancellation, upstream task cancellation, or shutdown — and no prior error was already propagating.","commonSituations":"User cancels a task in the Paperclip board; orchestrator shuts down and cancels in-flight commands; parent request aborted, cascading an abort into the sandbox call.","solutions":["This is expected on cancellation — catch it and treat the command as cancelled, not failed.","If unexpected, audit who owns the AbortSignal and why abort() was called.","Use signal.reason to distinguish cancellation causes before treating this as an error.","Ensure partial stdout/stderr captured before abort are preserved if needed."],"exampleFix":"// before\ntry { await run(cmd); } catch (e) { reportFailure(e); }\n// after\ntry { await run(cmd); } catch (e) {\n  if (e.message === \"CreateOS command was cancelled.\") return cancelledResult();\n  reportFailure(e);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await execute(lease, cmd, { signal });\n} catch (e) {\n  if (e.message === \"CreateOS command was cancelled.\") {\n    return { cancelled: true, partialOutput: captured }; // expected path\n  }\n  throw e;\n}","preventionTips":["Track AbortSignal ownership so unexpected aborts are diagnosable.","Set signal.reason on abort() to distinguish cancellation causes.","Treat this error as a cancellation signal, not a failure, in orchestrators."],"tags":["abort","cancellation","sandbox","process"],"backgroundTag":"thread-interrupted","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}