paperclipai/paperclip · error

CreateOS process output has a sequence gap.

Error message

CreateOS process output has a sequence gap.

What it means

A data event's seq skipped ahead of the expected cursor (seq !== cursor + 1 after filtering duplicates), indicating a lost frame between the server and client. Since output ordering/integrity cannot be guaranteed, the plugin fails closed rather than silently dropping bytes.

Solutions

  1. Re-run the command; a fresh process starts at seq 1 and avoids the gap.
  2. If reconnecting frequently, investigate network stability between client and CreateOS host.
  3. Check server-side buffering/retention settings and replica consistency for the /connect endpoint.
  4. Do not reconnect past the gap: the plugin intentionally refuses to resume beyond missing data.

Example fix

// before
connect(after=41) -> first event seq 43   // frame 42 lost -> gap
// after
re-run execute() on a fresh process       // seq restarts at 1, no gap
Defensive patterns

Strategy: try-catch

Try / catch

try { await execute(client, params, signal); }
catch (e) {
  if (e instanceof Error && e.message === "CreateOS process output has a sequence gap.") {
    // lost frame: re-run on a fresh process; never resume the gapped stream
  } else throw e;
}

Prevention

When it happens

Trigger: The /connect?after=cursor stream resumes at a sequence beyond cursor+1 — e.g. the server rotated or trimmed buffered frames, a reconnect landed on a different replica, or the server skipped events under load.

Common situations: Reconnect after a network blip where the server no longer holds frames from the old cursor; CreateOS clustering/replica mismatch; server-side buffer trimming under memory pressure.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/af971e2246afd330. Report an issue: GitHub.

Appendix: source

Thrown at packages/plugins/sandbox-providers/createos/src/execute.ts:156

      try {
        response = await client.request(`${base}/${processId}/connect?after=${cursor}`, { signal });
      } catch (error) {
        if (error instanceof CreateosApiError && error.status === 410) {
          throw new Error("CreateOS process output was evicted before it could be read.");
        }
        if (signal.aborted || (error instanceof CreateosApiError && error.status < 500 && error.status !== 429)) throw error;
        if (++reconnects > 3) throw new Error("CreateOS process output connection failed.");
        await delay(250, undefined, { signal });
        continue;
      }
      try {
        for await (const event of events(response)) {
          if (event.type === "heartbeat") continue;
          if (event.type === "data") {
            const seq = event.seq;
            if (typeof seq !== "number" || !Number.isSafeInteger(seq) || seq < 1) throw new Error("CreateOS process sequence is invalid.");
            if (seq <= cursor) continue;
            if (seq !== cursor + 1) throw new Error("CreateOS process output has a sequence gap.");
            if ((event.stream !== "stdout" && event.stream !== "stderr") ||
                typeof event.data_base64 !== "string" ||
                !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(event.data_base64)) {
              throw new Error("CreateOS process output is invalid.");
            }
            output.write(event.stream, Buffer.from(event.data_base64, "base64"));
            cursor = seq;
          } else if (event.type === "exit") {
            const exitCode = event.exit_code;
            const exitSignal = event.signal;
            if (!(typeof exitCode === "number" && Number.isInteger(exitCode)) &&
                !(typeof exitSignal === "string" && /^SIG[A-Z0-9]+$/.test(exitSignal))) {
              throw new Error("CreateOS process exit status is missing.");
            }
            completed = true;
            output.finish();
            return {
              exitCode: typeof exitCode === "number" ? exitCode : null,

View on GitHub (pinned to 3f1d897a7c)