paperclipai/paperclip · error · Error

sync wrote invalid result JSON

Error message

${input.label} sync wrote invalid result JSON: ${error instanceof Error ? error.message : String(error)}

What it means

Protocol-parsing failure after a sandbox sync upload: the shell pipeline (with optional sha verify) exited successfully but its trailing '{"uploaded":true}' marker failed to parse as JSON, so the upload result cannot be trusted from the command output alone.

Solutions

  1. Inspect the JSON error and retry the ${input.label} sync.
  2. Check for truncated writes in the sync result channel.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at packages/adapter-utils/src/sandbox-callback-bridge.ts:1527 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at packages/adapter-utils/src/sandbox-callback-bridge.ts:1667

 * `sha256sum` nor `shasum` — then the skip cannot be proven and we conservatively
 * re-upload (and the post-upload verify is best-effort, as noted inline).
 */
export async function syncRemoteTextFileWithHashSkip(input: {
  runner: CommandManagedRuntimeRunner;
  remoteCwd: string;
  remoteDir: string;
  remotePath: string;
  body: string;
  // Human-readable noun phrase used in fail-loud messages, e.g.
  // "Sandbox callback bridge entrypoint" / "Process session remote script".
  label: string;
  // Short action label for `requireSuccessfulResult`, e.g.
  // "sync sandbox callback bridge entrypoint".
  action: string;
  lockDir: string;
  timeoutMs?: number | null;
  shellCommand?: "bash" | "sh" | null;
}): Promise<{ uploaded: boolean; sha256: string }> {
  const timeoutMs = normalizeTimeoutMs(input.timeoutMs, DEFAULT_BRIDGE_RESPONSE_TIMEOUT_MS);
  const shellCommand = preferredShellForSandbox(input.shellCommand);
  const remotePartial = `${input.remotePath}.partial`;
  const remoteUploadPath = `${input.remotePath}.paperclip-upload.b64`;
  const base64Body = toBuffer(Buffer.from(input.body, "utf8")).toString("base64");
  const sha256 = createHash("sha256").update(input.body, "utf8").digest("hex");

  const syncResult = await runShell(
    input.runner,
    input.remoteCwd,
    [
      "set -eu",
      `remote_dir=${shellQuote(input.remoteDir)}`,
      `remote_path=${shellQuote(input.remotePath)}`,
      `remote_partial=${shellQuote(remotePartial)}`,
      `remote_upload=${shellQuote(remoteUploadPath)}`,
      `lock_dir=${shellQuote(input.lockDir)}`,
      `expected_sha=${shellQuote(sha256)}`,

View on GitHub (pinned to 3f1d897a7c)