{"record":{"id":"d562655364eba9de","repo":"invoke-ai/InvokeAI","slug":"base-url-must-not-start-with-reserved-path-segment","errorCode":null,"errorMessage":"base_url must not start with reserved path segment '/{first_segment}'","messagePattern":"base_url must not start with reserved path segment '/(.+?)'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/config/config_default.py","lineNumber":323,"sourceCode":"    @classmethod\n    def validate_base_url(cls, v: Optional[str]) -> Optional[str]:\n        \"\"\"Normalize the reverse-proxy base path: ensure a single leading slash, no trailing slash.\n\n        Empty values and a bare `/` normalize to `None` (feature disabled).\n\n        Reject base paths whose first segment collides with a real route prefix (`/api`, `/ws`, ...):\n        such a value silently bricks the server in both proxy styles (the sub-path rewrite and\n        Starlette's own `root_path` stripping fight over the same prefix), with no hint at the cause,\n        so we fail fast instead.\n        \"\"\"\n        if v is None:\n            return None\n        v = v.strip().strip(\"/\")\n        if not v:\n            return None\n        first_segment = v.split(\"/\")[0]\n        if first_segment in RESERVED_BASE_URL_PREFIXES:\n            raise ValueError(f\"base_url must not start with reserved path segment '/{first_segment}'\")\n        return f\"/{v}\"\n\n    def update_config(self, config: dict[str, Any] | InvokeAIAppConfig, clobber: bool = True) -> None:\n        \"\"\"Updates the config, overwriting existing values.\n\n        Args:\n            config: A dictionary of config settings, or instance of `InvokeAIAppConfig`. If an instance of \\\n                `InvokeAIAppConfig`, only the explicitly set fields will be merged into the singleton config.\n            clobber: If `True`, overwrite existing values. If `False`, only update fields that are not already set.\n        \"\"\"\n\n        if isinstance(config, dict):\n            new_config = self.model_validate(config)\n        else:\n            new_config = config\n\n        for field_name in new_config.model_fields_set:\n            new_value = getattr(new_config, field_name)","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/config/config_default.py#L305-L341","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pick a non-reserved first path segment, e.g. /invokeai or /myapp instead of /api","Check RESERVED_BASE_URL_PREFIXES in config_default.py for the exact blocked names","Update the reverse-proxy configuration to match the new base_url"],"exampleFix":"// before (invokeai.yaml)\nbase_url: /api/invokeai   # 'api' is reserved\n// after\nbase_url: /invokeai","handlingStrategy":"validation","validationCode":"from invokeai.app.services.config.config_default import RESERVED_BASE_URL_PREFIXES\nfirst = (cfg.base_url or '').strip().strip('/').split('/')[0]\nassert first not in RESERVED_BASE_URL_PREFIXES, f\"base_url prefix /{first} is reserved\"","typeGuard":null,"tryCatchPattern":"try:\n    cfg = InvokeAIAppConfig(**overrides)\nexcept ValueError as e:\n    if 'reserved path segment' in str(e):\n        overrides['base_url'] = '/invokeai'\n        cfg = InvokeAIAppConfig(**overrides)","preventionTips":["Check RESERVED_BASE_URL_PREFIXES before choosing a proxy subpath","Prefer an app-specific prefix like /invokeai","Keep reverse-proxy and base_url in sync"],"tags":["config","validation","pydantic","routing"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}