invoke-ai/InvokeAI · error · RuntimeError

Failed to load api keys file {api_keys_file_path}: value for

Error message

Failed to load api keys file {api_keys_file_path}: value for '{field_name}' must be a string

What it means

load_external_api_keys validates that every recognized external-provider field in the API keys YAML is a string. A recognized field_name present with a non-string YAML value (int, list, nested mapping) raises this RuntimeError.

Source

Thrown at invokeai/app/services/config/config_default.py:659

    if not api_keys_file_path.exists():
        return {}

    with open(api_keys_file_path, "rt", encoding=locale.getpreferredencoding()) as file:
        loaded_api_keys: Any = yaml.safe_load(file)

    if loaded_api_keys is None:
        return {}

    if not isinstance(loaded_api_keys, dict):
        raise RuntimeError(f"Failed to load api keys file {api_keys_file_path}: expected a mapping")

    parsed_api_keys: dict[str, str] = {}
    for field_name in EXTERNAL_PROVIDER_CONFIG_FIELDS:
        value = loaded_api_keys.get(field_name)
        if value is None:
            continue
        if not isinstance(value, str):
            raise RuntimeError(
                f"Failed to load api keys file {api_keys_file_path}: value for '{field_name}' must be a string"
            )
        stripped_value = value.strip()
        if stripped_value:
            parsed_api_keys[field_name] = stripped_value

    return parsed_api_keys


@lru_cache(maxsize=1)
def get_config() -> InvokeAIAppConfig:
    """Get the global singleton app config.

    When first called, this function:
    - Creates a config object. `pydantic-settings` handles merging of settings from environment variables, but not the init file.
    - Retrieves any provided CLI args from the InvokeAIArgs class. It does not _parse_ the CLI args; that is done in the main entrypoint.
    - Sets the root dir, if provided via CLI args.
    - Logs in to HF if there is no valid token already.

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Quote the value in the YAML so it is a string: `openai: "12345"`
  2. Flatten any nested structures under the provider field to a single string value
  3. Re-run after checking each field name matches EXTERNAL_PROVIDER_CONFIG_FIELDS and maps to a plain string

Example fix

// before (api_keys.yml)
openai: 1234567890
// after

openai: "1234567890"
Defensive patterns

Strategy: type-guard

Validate before calling

import yaml
from pathlib import Path
from invokeai.app.services.config import EXTERNAL_PROVIDER_CONFIG_FIELDS
def all_values_strings(p: Path) -> bool:
    data = yaml.safe_load(p.read_text()) or {}
    return all(isinstance(data.get(f), str) for f in EXTERNAL_PROVIDER_CONFIG_FIELDS if f in data)

Type guard

def is_str_value(v: object) -> bool:
    return isinstance(v, str)

Try / catch

try:
    keys = load_external_api_keys(path)
except RuntimeError as e:
    logger.error(f"api keys value type wrong: {e}")
    raise SystemExit(1)

Prevention

When it happens

Trigger: api_keys_file_path contains a key in EXTERNAL_PROVIDER_CONFIG_FIELDS whose value parses as a non-string, e.g. `openai: 12345`, `openai:\n - part1`.

Common situations: Unquoted API keys that YAML coerces (numeric-looking keys, keys starting with special chars), or a nested config accidentally pasted under a provider field.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/67a0e6c2393350d3. Report an issue: GitHub.