{"record":{"id":"1a6721c43dfc0279","repo":"Hmbown/CodeWhale","slug":"hdc-file-recv-failed-r-stderr-trim-slice-0-300","errorCode":null,"errorMessage":"hdc file recv failed: ${r.stderr.trim().slice(0, 300)}","messagePattern":"hdc file recv failed: (.+?)","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/transport.mjs","lineNumber":310,"sourceCode":"  return { installed: rels.length, remotePlatform: reply.platform, agentPath: `${marker}/agent.mjs` };\n}\n\n/** hdc (HarmonyOS) executor. Commands run on-device; files pull to local tmp. */\nexport function hdcExec(computer) {\n  const targetArgs = computer.target ? [\"-t\", computer.target] : [];\n  const shell = (args, opts = {}) => run(\"hdc\", [...targetArgs, \"shell\", ...args], opts);\n  return {\n    kind: \"hdc\",\n    targetArgs,\n    run,\n    runOk,\n    shell,\n    async pullFile(remotePath, localPath, opts = {}) {\n      // HDC device captures use absolute paths; SSH agent paths are relative.\n      // Validate the remaining path with the same traversal/metacharacter guard.\n      safeRemotePath(typeof remotePath === \"string\" ? remotePath.replace(/^\\//, \"\") : remotePath);\n      const r = await run(\"hdc\", [...targetArgs, \"file\", \"recv\", remotePath, localPath], opts);\n      if (r.code !== 0) throw new ExecError(`hdc file recv failed: ${r.stderr.trim().slice(0, 300)}`, r);\n      return localPath;\n    },\n    async readFile(remotePath, opts = {}) {\n      // Containment: pull into a private mkdtemp dir and remove exactly that\n      // dir. Never rm() the parent of a file placed directly in os.tmpdir() —\n      // that recursively deletes the entire user temp directory.\n      const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), \"cu-hdc-\"));\n      try {\n        const tmp = path.join(dir, \"out\");\n        await this.pullFile(remotePath, tmp, opts);\n        return await fs.promises.readFile(tmp);\n      } finally {\n        // Cleanup must not replace downloaded bytes or the original I/O error.\n        await fs.promises.rm(dir, { recursive: true, force: true }).catch(() => {});\n      }\n    },\n  };\n}","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/transport.mjs#L292-L328","documentation":"pullFile() on the HDC (HarmonyOS) transport copies a file from the device with `hdc file recv`; a nonzero exit throws this ExecError embedding trimmed stderr (max 300 chars). Before running, the remote path is stripped of a leading '/' and validated by safeRemotePath to block traversal/metacharacters, so this error is about the hdc transfer itself failing.","triggerScenarios":"Calling executor.pullFile(remotePath, localPath) when hdc exits nonzero: device not connected, remote path does not exist on device, permission denied on device path, or localPath not writable.","commonSituations":"HarmonyOS device disconnected or unauthorized; typo'd device path (file absent); target selector (targetArgs) pointing at the wrong connected device; local destination directory missing; hdc daemon not running on the device.","solutions":["Verify device connectivity: hdc list targets shows the expected device","Confirm the file exists on device: hdc shell ls <remotePath>","Check the local destination directory exists and is writable","Read embedded stderr for the specific hdc failure (path, permission, connection)","Ensure the correct device target is selected in targetArgs if multiple devices are attached"],"exampleFix":"// before\nawait ex.pullFile(\"/data/log/app.log\", \"/tmp/app.log\"); // file missing on device\n// after\nconst ls = await run(\"hdc\", [...targetArgs, \"shell\", \"ls\", \"/data/log/app.log\"]);\nif (ls.code !== 0) throw new Error(`device file missing: /data/log/app.log`);\nawait ex.pullFile(\"/data/log/app.log\", \"/tmp/app.log\");","handlingStrategy":"validation","validationCode":"// confirm the device and file exist before pullFile\nconst targets = await run(\"hdc\", [\"list\", \"targets\"]);\nif (!targets.stdout.trim()) throw new Error(\"no hdc device connected\");\nconst ls = await run(\"hdc\", [...targetArgs, \"shell\", \"ls\", remotePath]);\nif (ls.code !== 0) throw new Error(`device file missing: ${remotePath}`);","typeGuard":"function isHdcRecvFailure(e) { return e instanceof ExecError && e.message.startsWith(\"hdc file recv failed\"); }","tryCatchPattern":"try {\n  const local = await ex.pullFile(remotePath, localPath);\n} catch (e) {\n  if (e.message.startsWith(\"hdc file recv failed\")) {\n    console.error(\"hdc recv failed:\", e.message); // embedded stderr: path vs connection\n    // reconnect device or correct the device path, then retry\n  }\n  throw e;\n}","preventionTips":["Run hdc list targets before device operations","Validate the device path exists with hdc shell ls","Ensure the local destination directory exists and is writable","Select the correct target when multiple devices are attached"],"tags":["hdc","file-transfer","harmonyos"],"backgroundTag":"file-transfer-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}