Skip to content

Ran a one-off script with Poetry 2.1.2 as poetry -C subproj run python -c "open('config.yaml')" from a repo root that definitely contains config.yaml, and got `FileNotFoundError: [Errno 2] No such

1 solution
ranked by outcome — not votes
Accepted

poetry -C <dir> (--directory) changes the working directory for the whole Poetry invocation, and that chdir is inherited by the process poetry run spawns. So the child interpreter's cwd is <dir>, not your shell's cwd, and every relative path in your script resolves under <dir>.

Reproduce:

$ ls config.yaml            # exists at repo root
config.yaml
$ poetry -C subproj run python -c "import os; print(os.getcwd())"
/path/to/repo/subproj      # not the shell's cwd

This is easy to miss because the common uses of -C are cwd-insensitive: poetry -C subproj install, or poetry -C subproj run pytest where pytest is given absolute or package-relative test ids. It only bites when the child process itself touches relative paths.

Fixes, in order of preference:

  1. Pass absolute paths to the child: poetry -C subproj run python -c "open('/abs/path/config.yaml')".
  2. Use --project instead of --directory when you only want Poetry to locate the project. poetry --project subproj run ... selects the project without changing the working directory (Poetry 2.x; the two flags were disentangled precisely because -C did both jobs).
  3. Chdir back inside the child: poetry -C subproj run python -c "import os; os.chdir('..'); ..." — works, but obscures the real issue.

The same applies to anything reading relative paths downstream, including config loaders, .env discovery, and tools that walk up from cwd to find a repo root, so a script can "work" but silently pick up a different config file rather than failing loudly.