python-poetry/poetry · error · PropertyNotFoundError

Key {'.'.join(keys)} not in config

Error message

Key {'.'.join(keys)} not in config

What it means

Same PropertyNotFoundError raised by FileConfigSource.get_property(), the TOML-file-backed config source. It reads the file (or defaults to {}) then walks the key segments; if any segment is missing it raises this error. Unlike DictConfigSource the data comes from a TOML file on disk, so the root cause is typically a missing or incomplete config file rather than an in-memory state issue.

Source

Thrown at src/poetry/config/file_config_source.py:43

    def __init__(self, file: TOMLFile) -> None:
        self._file = file

    @property
    def name(self) -> str:
        return str(self._file.path)

    @property
    def file(self) -> TOMLFile:
        return self._file

    def get_property(self, key: str | Sequence[str]) -> Any:
        keys = split_key(key)

        config = self.file.read() if self.file.exists() else {}

        for i, sub_key in enumerate(keys):
            if sub_key not in config:
                raise PropertyNotFoundError(f"Key {'.'.join(keys)} not in config")

            if i == len(keys) - 1:
                return config[sub_key]

            config = config[sub_key]

    def add_property(self, key: str | Sequence[str], value: Any) -> None:
        with self.secure() as config:
            keys = split_key(key)

            for i, sub_key in enumerate(keys):
                if sub_key not in config and i < len(keys) - 1:
                    config[sub_key] = table()

                if i == len(keys) - 1:
                    config[sub_key] = value
                    break

View on GitHub (pinned to 92b74dcfe3)

Solutions

  1. Check that the TOML file exists at the expected path (FileConfigSource.file.path) and inspect its contents.
  2. Catch PropertyNotFoundError and fall back to the global/merged config value via Config.get() which returns None for missing keys.
  3. Use add_property to set the key before reading it if it should always be present.

Example fix

# before
value = source.get_property(["repositories", "myrepo"])
# after
from poetry.config.config_source import PropertyNotFoundError
try:
    value = source.get_property(["repositories", "myrepo"])
except PropertyNotFoundError:
    value = config.get(["repositories", "myrepo"])  # falls through to merged config
Defensive patterns

Strategy: try-catch

Validate before calling

from poetry.config.config_source import PropertyNotFoundError

def safe_get_file(source, key, default=None):
    try:
        return source.get_property(key)
    except PropertyNotFoundError:
        return default

Type guard

def file_key_exists(source, key) -> bool:
    from poetry.config.config_source import PropertyNotFoundError
    try:
        source.get_property(key)
        return True
    except PropertyNotFoundError:
        return False

Try / catch

from poetry.config.config_source import PropertyNotFoundError

try:
    value = file_source.get_property(["repositories", "myrepo"])
except PropertyNotFoundError:
    # Key not present in the TOML config file (or file is missing)
    value = None

Prevention

When it happens

Trigger: Calling FileConfigSource.get_property(key) when the TOML file either does not exist (defaults to empty dict) or does not contain the requested key path. For instance reading ['repositories','myrepo'] from a poetry.toml that has no [repositories] table.

Common situations: Fresh project with no poetry.toml yet, a corrupted or partially-written config file, a key that was removed via remove_property (which prunes empty parent tables), or querying a key that only exists in the global config but not the local file.

Related errors


AI-assisted analysis of python-poetry/poetry@92b74dcfe3 (2026-08-04). Data as JSON: /data/errors/3b371a8edb648188.json. Report an issue: GitHub.