invoke-ai/InvokeAI · error · ValueError

base_url must not start with reserved path segment '/{first_

Error message

base_url must not start with reserved path segment '/{first_segment}'

What it means

validate_base_url strips and normalizes the configured base_url, then rejects any value whose first path segment is in RESERVED_BASE_URL_PREFIXES. These prefixes are reserved for InvokeAI's own routes, so shadowing them would break the API and UI.

Source

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

    @classmethod
    def validate_base_url(cls, v: Optional[str]) -> Optional[str]:
        """Normalize the reverse-proxy base path: ensure a single leading slash, no trailing slash.

        Empty values and a bare `/` normalize to `None` (feature disabled).

        Reject base paths whose first segment collides with a real route prefix (`/api`, `/ws`, ...):
        such a value silently bricks the server in both proxy styles (the sub-path rewrite and
        Starlette's own `root_path` stripping fight over the same prefix), with no hint at the cause,
        so we fail fast instead.
        """
        if v is None:
            return None
        v = v.strip().strip("/")
        if not v:
            return None
        first_segment = v.split("/")[0]
        if first_segment in RESERVED_BASE_URL_PREFIXES:
            raise ValueError(f"base_url must not start with reserved path segment '/{first_segment}'")
        return f"/{v}"

    def update_config(self, config: dict[str, Any] | InvokeAIAppConfig, clobber: bool = True) -> None:
        """Updates the config, overwriting existing values.

        Args:
            config: A dictionary of config settings, or instance of `InvokeAIAppConfig`. If an instance of \
                `InvokeAIAppConfig`, only the explicitly set fields will be merged into the singleton config.
            clobber: If `True`, overwrite existing values. If `False`, only update fields that are not already set.
        """

        if isinstance(config, dict):
            new_config = self.model_validate(config)
        else:
            new_config = config

        for field_name in new_config.model_fields_set:
            new_value = getattr(new_config, field_name)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Pick a non-reserved first path segment, e.g. /invokeai or /myapp instead of /api
  2. Check RESERVED_BASE_URL_PREFIXES in config_default.py for the exact blocked names
  3. Update the reverse-proxy configuration to match the new base_url

Example fix

// before (invokeai.yaml)
base_url: /api/invokeai   # 'api' is reserved
// after
base_url: /invokeai
Defensive patterns

Strategy: validation

Validate before calling

from invokeai.app.services.config.config_default import RESERVED_BASE_URL_PREFIXES
first = (cfg.base_url or '').strip().strip('/').split('/')[0]
assert first not in RESERVED_BASE_URL_PREFIXES, f"base_url prefix /{first} is reserved"

Try / catch

try:
    cfg = InvokeAIAppConfig(**overrides)
except ValueError as e:
    if 'reserved path segment' in str(e):
        overrides['base_url'] = '/invokeai'
        cfg = InvokeAIAppConfig(**overrides)

Prevention

When it happens

Trigger: Configuring base_url starting with a reserved segment such as /api, /docs, /static etc. (whatever RESERVED_BASE_URL_PREFIXES contains), e.g. base_url: api/v2 or base_url: /docs-site in invokeai.yaml or via env.

Common situations: Deploying behind a reverse proxy and choosing a subpath that collides with internal routes; typos like base_url: /api-key; reusing an existing proxy prefix without checking the reserved list.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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