oraios/serena · error · FileNotFoundError

Specified a relative working directory ({cwd}), but the resu

Error message

Specified a relative working directory ({cwd}), but the resulting path is not a directory: {_cwd}

What it means

Serena's ExecuteShellCommandTool resolves a relative cwd against the project root. If the joined path is not an existing directory, apply() raises FileNotFoundError with this message. The command is never executed, so no shell state was changed.

Source

Thrown at src/serena/tools/cmd_tools.py:46

          * processes that require user interaction.

        :param command: the shell command to execute
        :param cwd: the working directory to execute the command in. If None, the project root will be used.
        :param capture_stderr: whether to capture and return stderr output
        :param max_answer_chars: if the output is longer than this number of characters,
            no content will be returned. -1 means using the default value, don't adjust unless there is no other way to get the content
            required for the task.
        :return: a JSON object containing the command's stdout and optionally stderr output
        """
        if cwd is None:
            _cwd = self.get_project_root()
        else:
            if os.path.isabs(cwd):
                _cwd = cwd
            else:
                _cwd = os.path.join(self.get_project_root(), cwd)
                if not os.path.isdir(_cwd):
                    raise FileNotFoundError(
                        f"Specified a relative working directory ({cwd}), but the resulting path is not a directory: {_cwd}"
                    )

        result = execute_shell_command(command, cwd=_cwd, capture_stderr=capture_stderr)
        result = result.model_dump_json()
        return self._limit_length(result, max_answer_chars)

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Create the missing directory (mkdir -p) or correct the typo in the relative cwd path
  2. Pass an absolute path for cwd so it is used verbatim (os.path.isabs branch)
  3. Verify with os.path.isdir(os.path.join(project_root, cwd)) before invoking the tool
  4. If cwd is optional, omit it to run in the project root

Example fix

// before
result = agent.execute_shell_command("npm test", cwd="packages/ap")
// after
cwd = "packages/app"
assert os.path.isdir(os.path.join(project_root, cwd)), cwd
result = agent.execute_shell_command("npm test", cwd=cwd)
Defensive patterns

Strategy: validation

Validate before calling

import os
cwd_abs = cwd if os.path.isabs(cwd) else os.path.join(project_root, cwd)
if not os.path.isdir(cwd_abs):
    raise NotADirectoryError(cwd_abs)
result = agent.execute_shell_command(command, cwd=cwd)

Type guard

def valid_cwd(cwd: str, root: str) -> bool:
    p = cwd if os.path.isabs(cwd) else os.path.join(root, cwd)
    return os.path.isdir(p)

Try / catch

try:
    result = agent.execute_shell_command(cmd, cwd=cwd)
except FileNotFoundError as e:
    if "not a directory" in str(e):
        os.makedirs(os.path.join(project_root, cwd), exist_ok=True)
        result = agent.execute_shell_command(cmd, cwd=cwd)
    else:
        raise

Prevention

When it happens

Trigger: Calling execute_shell_command (the apply method) with cwd="subdir" when subdir does not exist under the project root, or with a file path instead of a directory, or with a typo'd/renamed relative directory.

Common situations: Running build/test commands from agents after a refactor moved the directory; using an absolute-style path string without leading slash (treated as relative); project checked out without submodules or generated folders that the command expects as cwd.

Related errors


AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29). Data as JSON: /api/errors/40ce7b45da663db6. Report an issue: GitHub.