{"record":{"id":"cb687ca84bd95425","repo":"paperclipai/paperclip","slug":"sandbox-callback-bridge-response-write-wrote-inval","errorCode":null,"errorMessage":"Sandbox callback bridge response write wrote invalid result JSON: ${error instanceof Error ? error.message : String(error)}","messagePattern":"Sandbox callback bridge response write wrote invalid result JSON: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/sandbox-callback-bridge.ts","lineNumber":607,"sourceCode":"          \"if [ -f \\\"$response_path\\\" ]; then\",\n          \"  printf '{\\\"wrote\\\":false}\\\\n'\",\n          \"  exit 0\",\n          \"fi\",\n          \"cat > \\\"$temp_path\\\"\",\n          \"mv \\\"$temp_path\\\" \\\"$response_path\\\"\",\n          \"printf '{\\\"wrote\\\":true}\\\\n'\",\n        ].join(\"\\n\"),\n        timeoutMs,\n        shellCommand,\n        body,\n      );\n      requireSuccessfulResult(`write bridge response ${responsePath}`, result);\n      try {\n        return {\n          wrote: JSON.parse(result.stdout.trim())?.wrote === true,\n        };\n      } catch (error) {\n        throw new Error(\n          `Sandbox callback bridge response write wrote invalid result JSON: ${error instanceof Error ? error.message : String(error)}`,\n        );\n      }\n    },\n    rename: async (fromPath, toPath) => {\n      await runChecked(\n        `rename ${fromPath}`,\n        `mkdir -p ${shellQuote(path.posix.dirname(toPath))} && mv ${shellQuote(fromPath)} ${shellQuote(toPath)}`,\n      );\n    },\n    remove: async (remotePath) => {\n      await runChecked(`remove ${remotePath}`, `rm -rf ${shellQuote(remotePath)}`);\n    },\n  };\n}\n\nasync function writeBridgeResponse(\n  client: SandboxCallbackBridgeQueueClient,","sourceCodeStart":589,"sourceCodeEnd":625,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/sandbox-callback-bridge.ts#L589-L625","documentation":"Thrown by the command-managed writeResponseFile after the remote shell script completed successfully (requireSuccessfulResult passed, exit code 0) but stdout could not be parsed as JSON containing a wrote field. The script is expected to print {\"wrote\":true} or {\"wrote\":false}; anything else indicates the remote shell emitted unexpected text (banner, set -x trace, warning) that broke JSON.parse or did not contain wrote.","triggerScenarios":"Remote SSH session prints a login banner before the script, the shell is run with -x tracing that pollutes stdout, a remote .bashrc echoes text on non-interactive shells, or a partial script timeout left stdout truncated. The JSON.parse call at sandbox-callback-bridge.ts:604 throws, which is wrapped into this error message including the underlying parse error.","commonSituations":"SSH banners from MOTD or PAM modules that echo to stdout instead of stderr; interactive shell configs (PS1, echo statements) sourced for non-interactive sessions; shells with set -v or set -x enabled globally; or PATH/locale warnings printed to stdout. The shell quote/redirect discipline in the script keeps stderr separate, but any stdout noise trips this guard.","solutions":["Suppress remote shell noise: ensure the bridge runs with a clean non-interactive shell (bash --noprofile --norc -c '...') and that no .bashrc echoes to stdout.","Move any MOTD/banner output to stderr on the remote host (PAM, sshd config).","Check the runner's shellCommand setting — prefer bash with --noprofile --norc to skip startup files that emit stdout.","Capture the raw stdout in your error handler to see exactly what the remote printed; the message includes the parse error but not the raw stdout, so add a log of result.stdout before parsing when debugging."],"exampleFix":"// before: remote ~/.bashrc echoes a greeting to stdout\n// echo \"Welcome\"  # <-- delete or redirect to stderr\n\n// after: keep startup files silent on non-interactive shells\n// in ~/.bashrc\nif [ -z \"$PS1\" ]; then return; fi  # skip rest for non-interactive","handlingStrategy":"validation","validationCode":"async function preflightRemoteShellIsSilent(runner: CommandManagedRuntimeRunner, remoteCwd: string): Promise<void> {\n  const result = await runShell(runner, remoteCwd, 'printf \\'{\"wrote\":true}\\\\n\\'', 5000, \"bash\");\n  try {\n    if (JSON.parse(result.stdout.trim())?.wrote !== true) {\n      throw new Error(`Unexpected stdout: ${result.stdout}`);\n    }\n  } catch (error) {\n    throw new Error(`Remote shell pollutes stdout; disable MOTD/.bashrc echoes: ${String(error)}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await client.writeResponseFile(responsePath, body, { requestPath });\n} catch (error) {\n  if (error instanceof Error && error.message.startsWith(\"Sandbox callback bridge response write wrote invalid result JSON\")) {\n    throw new BridgeError(\"Remote shell wrote non-JSON to stdout. Suppress MOTD/.bashrc echoes or switch to bash --noprofile --norc.\", { cause: error });\n  }\n  throw error;\n}","preventionTips":["Use a clean non-interactive shell (bash --noprofile --norc -c '...') via the bridge's shellCommand option.","Move MOTD/banner output to stderr on the remote host (sshd PrintMotd no, Banner none).","Guard ~/.bashrc with `if [ -z \\\"$PS1\\\" ]; then return; fi` so non-interactive sessions skip echoing logic.","When debugging, log result.stdout verbatim before parsing to see the offending line."],"tags":["bridge","remote-runtime","shell","json","callback-bridge"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}