{"record":{"id":"6cca697f3a7d3e6d","repo":"paperclipai/paperclip","slug":"could-not-determine-remote-file-size-for-remotep","errorCode":null,"errorMessage":"Could not determine remote file size for ${remotePath}","messagePattern":"Could not determine remote file size for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/command-managed-runtime.ts","lineNumber":290,"sourceCode":"          const end = Math.min(total, offset + REMOTE_WRITE_FALLBACK_DECODED_CHUNK_SIZE);\n          const chunk = buffer.subarray(offset, end).toString(\"base64\");\n          await runShell(`base64 -d >> ${shellQuote(remoteTempPath)}`, { stdin: chunk });\n          await options?.onProgress?.(end, total);\n        }\n        await runShell(`mv -f ${shellQuote(remoteTempPath)} ${shellQuote(remotePath)}`);\n        await options?.onProgress?.(total, total);\n      } finally {\n        await bestEffortRemoveRemotePath(client, remoteTempPath);\n      }\n    },\n    readFile: async (remotePath, options) => {\n      // Chunked reads intentionally query the remote size first, even without\n      // a progress sink, so each sandbox RPC stays bounded and truncation is\n      // detected without materializing the whole file as one stdout string.\n      const sizeResult = await runShell(`wc -c < ${shellQuote(remotePath)}`);\n      const totalBytes = Number.parseInt(sizeResult.stdout.trim(), 10);\n      if (!Number.isFinite(totalBytes) || totalBytes < 0) {\n        throw new Error(`Could not determine remote file size for ${remotePath}`);\n      }\n\n      // Read in bounded remote chunks so the runner never has to materialize a\n      // single base64 stdout string for the whole archive. The client API still\n      // returns the decoded file as a Buffer, but every command result stays\n      // small enough for provider-backed sandbox RPCs.\n      const decodedChunks: Buffer[] = [];\n      let decodedSoFar = 0;\n      if (totalBytes === 0) {\n        await options?.onProgress?.(0, 0);\n        return Buffer.alloc(0);\n      }\n      for (let chunkIndex = 0; decodedSoFar < totalBytes; chunkIndex++) {\n        const result = await runShell(\n          `dd if=${shellQuote(remotePath)} bs=${REMOTE_READ_CHUNK_BYTES} skip=${chunkIndex} count=1 2>/dev/null | base64`,\n        );\n        const chunk = Buffer.from(result.stdout.replace(/\\s+/g, \"\"), \"base64\");\n        if (chunk.byteLength === 0) break;","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/command-managed-runtime.ts#L272-L308","documentation":"Thrown by the readFile method of the command-managed runtime client when 'wc -c < <remotePath>' returns a value that is not a finite non-negative integer. This size probe is the first step of a chunked remote read: it determines how many dd-based chunks to fetch. If the size cannot be determined, the bounded read loop cannot proceed safely.","triggerScenarios":"Calling client.readFile(remotePath) when the remote 'wc -c' command output cannot be parsed as a non-negative finite integer. This happens when the file does not exist (wc prints an error and the exit code is non-zero, but the error is already caught by requireSuccessfulResult), or when wc produces unexpected output (e.g., locale-dependent formatting, a symlink loop, or a special file like /dev/zero where wc may hang or return unexpected values).","commonSituations":"Reading from a path that is a FIFO, device file, or other special file where wc -c behaves unexpectedly. A locale or wc implementation that formats output differently. The file was deleted between the size probe and the read. The sandbox environment has a non-standard wc binary.","solutions":["Verify the remote path exists and is a regular file: run 'ls -la <remotePath>' or use client.listFiles on the parent directory.","If reading a special file (FIFO, device), read it with a different mechanism (e.g., client.run with cat) instead of readFile.","Check the sandbox's wc implementation: run 'wc -c < /dev/null' to confirm it returns 0.","Handle race conditions by retrying or ensuring the file is not modified/deleted during the read."],"exampleFix":"// before: reading a non-regular file\nawait client.readFile('/workspace/pipe'); // FIFO -> wc returns unexpected value\n\n// after: check file type first, use run() for special files\nconst result = await client.run(`file ${shellQuote(remotePath)}`);\n// if special file, use cat instead:\nconst data = await client.run(`cat ${shellQuote(remotePath)} | base64`);","handlingStrategy":"validation","validationCode":"async function isRemoteFileReadable(client: SandboxManagedRuntimeClient, remotePath: string): Promise<boolean> {\n  try {\n    // Verify the path is a regular file and wc works\n    const result = await client.run(`test -f ${shellQuote(remotePath)} && wc -c < ${shellQuote(remotePath)}`);\n    const size = Number.parseInt(result.stdout.trim(), 10);\n    return Number.isFinite(size) && size >= 0;\n  } catch {\n    return false;\n  }\n}\n\n// Call before client.readFile:\nif (!(await isRemoteFileReadable(client, remotePath))) {\n  throw new Error(`Remote path ${remotePath} is not a readable regular file.`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const data = await client.readFile(remotePath);\n} catch (error) {\n  if (error instanceof Error && error.message.includes('Could not determine remote file size')) {\n    // The file may not exist or may be a special file\n    // Check file type and existence, then retry or use an alternative read method\n    const fileInfo = await client.run(`file ${shellQuote(remotePath)} 2>&1 || echo 'missing'`);\n    console.error('File info:', fileInfo.stdout);\n  }\n  throw error;\n}","preventionTips":["Before calling readFile, verify the path is a regular file using client.run('test -f <path>').","Avoid reading special files (FIFOs, device nodes) through readFile—use client.run with cat instead.","Check the sandbox's wc implementation with 'wc -c < /dev/null' to ensure it returns 0 for empty files.","Handle file-not-found separately by checking existence before readFile."],"tags":["runtime","sandbox","file-read","adapter-utils"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}