{"record":{"id":"adc55a69b97efa95","repo":"sinelaw/fresh","slug":"empty-path","errorCode":null,"errorMessage":"empty path","messagePattern":"empty path","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/services/remote/agent.py","lineNumber":50,"sourceCode":"    with write_lock:\n        sys.stdout.write(line)\n        sys.stdout.flush()\n\n\ndef b64(data):\n    \"\"\"Encode bytes to base64 string.\"\"\"\n    return base64.b64encode(data).decode(\"ascii\")\n\n\ndef unb64(s):\n    \"\"\"Decode base64 string to bytes.\"\"\"\n    return base64.b64decode(s)\n\n\ndef validate_path(p):\n    \"\"\"Validate and canonicalize a path.\"\"\"\n    if not p:\n        raise ValueError(\"empty path\")\n    expanded = os.path.expanduser(p)\n    if not os.path.isabs(expanded):\n        expanded = os.path.abspath(expanded)\n    return os.path.realpath(expanded)\n\n\n# === File Operations ===\n\n\ndef cmd_read(id, p):\n    \"\"\"Read file contents, streaming in chunks for large files.\"\"\"\n    path = validate_path(p[\"path\"])\n    off = p.get(\"off\", 0)\n    length = p.get(\"len\")\n\n    with open(path, \"rb\") as f:\n        if off:\n            f.seek(off)","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/services/remote/agent.py#L32-L68","documentation":"validate_path in the remote agent service canonicalizes any path before file operations (read, write, sudo_write, stat, ls, rm). It raises ValueError('empty path') when the argument is falsy (None or \"\"), because a canonicalized empty path is meaningless and would otherwise resolve to the process CWD and allow unintended operations.","triggerScenarios":"Any of the remote agent commands cmd_read, cmd_write, cmd_sudo_write, cmd_stat, cmd_ls, cmd_rm invoked with p=None or p=\"\" — e.g. a client request whose 'path' field is missing, null, or an empty string reaches agent.py:50.","commonSituations":"API clients omitting the path field in the JSON request body; frontends sending empty inputs from unfilled form fields; protocol/serialization bugs dropping empty strings; defaults where None is used for 'not provided'.","solutions":["Provide a non-empty absolute (or workspace-relative) path in the request.","On the client side, validate the path is a non-empty string before sending the command.","If the path is meant to be optional, handle that in the command layer before calling validate_path instead of passing \"\"/None.","Catch ValueError from the command and return a clear client error indicating the missing path parameter."],"exampleFix":"// before\nresult = agent.cmd_read(\"\")\n\n// after\npath = request.get(\"path\") or \"\"\nif not path:\n    raise BadRequest(\"'path' is required and must be non-empty\")\nresult = agent.cmd_read(path)","handlingStrategy":"validation","validationCode":"if not isinstance(p, str) or not p:\n    raise ValueError(\"path must be a non-empty string\")","typeGuard":"def is_valid_path(p) -> bool:\n    return isinstance(p, str) and bool(p)","tryCatchPattern":"try:\n    canonical = validate_path(p)\nexcept ValueError as e:\n    if str(e) == \"empty path\":\n        return error_response(400, \"'path' is required and must be non-empty\")\n    raise","preventionTips":["Validate that the path field is present and non-empty at the API boundary before dispatching commands.","Distinguish 'optional path' from 'empty path' explicitly in request schemas.","Use request validation (schema/pydantic) so missing path fields are rejected before reaching validate_path.","Test the read/write/ls/rm commands with empty and null path payloads."],"tags":["validation","empty-argument","path","remote-agent"],"backgroundTag":"empty-required-field","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"}