{"record":{"id":"9eee19417e4cbb83","repo":"paperclipai/paperclip","slug":"run-log-tail-tick-returned-unparseable-output","errorCode":null,"errorMessage":"Run log tail tick returned unparseable output.","messagePattern":"Run log tail tick returned unparseable output\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/adapter-utils/src/sandbox-run-log-stream.ts","lineNumber":183,"sourceCode":"      }\n    }\n\n    async function tick(): Promise<void> {\n      const result = await options.runner.execute({\n        command: shellCommand,\n        args: shellCommandArgs(buildTickScript()),\n        cwd: options.remoteCwd,\n        env: { [SANDBOX_EXEC_CHANNEL_ENV]: SANDBOX_EXEC_CHANNEL_BRIDGE },\n        timeoutMs: tickTimeoutMs,\n      });\n      if (result.timedOut || (result.exitCode ?? 1) !== 0) {\n        throw new Error(\n          `Run log tail tick failed (exit ${result.exitCode ?? \"null\"}${result.timedOut ? \", timed out\" : \"\"}).`,\n        );\n      }\n      const sections = parseTickOutput(result.stdout);\n      if (!sections) {\n        throw new Error(\"Run log tail tick returned unparseable output.\");\n      }\n      await emitBytes(streams[0], sections.stdout);\n      await emitBytes(streams[1], sections.stderr);\n    }\n\n    async function loop(): Promise<void> {\n      let consecutiveFailures = 0;\n      while (!stopped) {\n        await sleep(pollIntervalMs);\n        if (stopped) break;\n        try {\n          await tick();\n          consecutiveFailures = 0;\n        } catch {\n          consecutiveFailures += 1;\n          if (consecutiveFailures >= maxConsecutiveFailures) {\n            degraded = true;\n            break;","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/sandbox-run-log-stream.ts#L165-L201","documentation":"Thrown by tick() after a successful (exit 0) tail command when the captured stdout does not contain the expected marker frame: a TAIL_MARKER_STDOUT line, a later TAIL_MARKER_STDERR line, and a later TAIL_MARKER_END line, in that order. It means the remote shell produced structurally unexpected output — e.g. a login banner, a different shell that does not support printf, or a partial capture cut between markers.","triggerScenarios":"parseTickOutput returns null because indexOf markers are missing or mis-ordered: stdoutIndex<0, stderrIndex<stdoutIndex, or endIndex<stderrIndex. Happens when remote shell is not POSIX sh (printf flags differ), a banner precedes the first marker, or stdout was truncated mid-frame.","commonSituations":"Remote default shell is fish/csh which mishandle the printf/head/base64 pipeline; .bashrc prints to stdout; tickTimeoutMs cut the output before TAIL_MARKER_END; a wrapper script injects text; locale/encoding corrupts the marker bytes.","solutions":["Log result.stdout verbatim on parse failure to see what broke the marker frame.","Ensure the remote login shell for the exec channel is POSIX (sh/bash) and non-interactive (no profile output to stdout).","Increase tickTimeoutMs so the full marker frame is captured atomically.","Confirm base64/tail/head exist on the remote host and the marker constants are not accidentally redefined."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function validateTickFrame(stdout: string): void {\n  const lines = stdout.split(/\\r?\\n/);\n  const s = lines.indexOf(TAIL_MARKER_STDOUT);\n  const e = lines.indexOf(TAIL_MARKER_STDERR);\n  const end = lines.indexOf(TAIL_MARKER_END);\n  if (s < 0 || e < s || end < e) {\n    throw new Error(`tail frame malformed; first 200 bytes: ${stdout.slice(0, 200)}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try { await tick(); } catch (err) { consecutiveFailures += 1; /* loop tolerates up to maxConsecutiveFailures */ }","preventionTips":["Use a non-interactive POSIX shell for the exec channel (no profile output to stdout).","Keep tickTimeoutMs high enough to capture the full marker frame atomically.","Confirm tail/head/base64/printf exist on the remote host."],"tags":["sandbox","log-stream","parsing","shell","markers"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}