{"record":{"id":"8cbf3a525ea8a3e6","repo":"sinelaw/fresh","slug":"sudo-tee-failed-stderr-decode-strip","errorCode":null,"errorMessage":"sudo tee failed: {stderr.decode().strip()}","messagePattern":"sudo tee failed: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/services/remote/agent.py","lineNumber":137,"sourceCode":"    path = validate_path(p[\"path\"])\n    data = unb64(p[\"data\"])\n\n    # Get original metadata to preserve permissions\n    mode = p.get(\"mode\")\n    uid = p.get(\"uid\")\n    gid = p.get(\"gid\")\n\n    # Use sudo tee to write the file\n    proc = subprocess.Popen(\n        [\"sudo\", \"tee\", path],\n        stdin=subprocess.PIPE,\n        stdout=subprocess.DEVNULL,\n        stderr=subprocess.PIPE,\n    )\n    _, stderr = proc.communicate(data)\n\n    if proc.returncode != 0:\n        raise RuntimeError(f\"sudo tee failed: {stderr.decode().strip()}\")\n\n    # Restore permissions and ownership if provided\n    if mode is not None:\n        subprocess.run([\"sudo\", \"chmod\", f\"{mode:o}\", path], check=True,\n                       capture_output=True)\n    if uid is not None and gid is not None:\n        subprocess.run([\"sudo\", \"chown\", f\"{uid}:{gid}\", path], check=True,\n                       capture_output=True)\n\n    send(id, r={\"size\": len(data)})\n\n\ndef cmd_stat(id, p):\n    \"\"\"Get file/directory metadata.\"\"\"\n    path = validate_path(p[\"path\"])\n    follow = p.get(\"link\", True)\n\n    st = os.stat(path, follow_symlinks=follow)","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/services/remote/agent.py#L119-L155","documentation":"cmd_sudo_write writes file contents on a remote host by piping data into `sudo tee <path>`. When the sudo/tee process exits non-zero, the helper raises RuntimeError embedding tee's stderr so the editor's remote-write operation fails loudly instead of silently leaving the file unwritten. It usually means sudo could not complete the write: missing sudo credentials, non-interactive sudo, bad path, or filesystem errors.","triggerScenarios":"Calling the remote sudo-write RPC (cmd_sudo_write in agent.py) when the spawned `sudo tee` process returns a non-zero exit code — e.g. sudo requires a password but no TTY/askpass is available (`sudo: a terminal is required`), the user is not in sudoers, the target path's directory doesn't exist or is unwritable, or the disk is full/read-only.","commonSituations":"Editing root-owned config files (e.g. /etc/...) over the remote agent session where the SSH connection has no TTY allocated, so sudo cannot prompt; sudo timeout expired mid-session; NOPASSWD not configured for the agent user; path typos or the file's parent directory was removed.","solutions":["Read the stderr embedded in the message to see the actual sudo/tee failure cause (password prompt, permission, no such file).","Enable passwordless or cached sudo for the agent user (configure NOPASSWD in sudoers, or run sudo -v first to cache credentials).","Run the agent over a connection that allows sudo (allocate a TTY, or use `sudo -n` in an environment with cached credentials).","Verify the target path exists/is writable by root (parent directory present, filesystem not read-only or full)."],"exampleFix":"// before: failing because sudo cannot prompt for a password over a non-TTY channel\nraise RuntimeError(f\"sudo tee failed: sudo: a terminal is required...\")\n\n// after: grant the agent user passwordless tee for the target, or pre-cache credentials\n# /etc/sudoers.d/agent\nagent ALL=(root) NOPASSWD: /usr/bin/tee\n# or, before editing: sudo -v","handlingStrategy":"try-catch","validationCode":"import subprocess\ndef sudo_available(path):\n    r = subprocess.run([\"sudo\", \"-n\", \"true\"], capture_output=True)\n    return r.returncode == 0\n# also check: parent dir exists and sudo -n works before cmd_sudo_write","typeGuard":null,"tryCatchPattern":"try:\n    result = sudo_write(path, data)\nexcept RuntimeError as e:\n    if \"terminal is required\" in str(e) or \"a password is required\" in str(e):\n        # prompt for credentials / run sudo -v, then retry\n        ...\n    else:\n        log.error(\"sudo tee failed: %s\", e)","preventionTips":["Configure NOPASSWD sudoers for the agent user or pre-cache credentials with sudo -v.","Check `sudo -n true` succeeds before attempting sudo writes.","Verify the target path and its parent directory exist and are root-writable."],"tags":["sudo","file-write","remote-agent","subprocess","permission-denied"],"backgroundTag":"file-write-failed","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}