xtekky/gpt4free · error · ValueError

Invalid AZURE_ROUTES environment variable format: {routes}

Error message

Invalid AZURE_ROUTES environment variable format: {routes}

What it means

AZURE_ROUTES must be a JSON object mapping model names to Azure OpenAI api_endpoint URLs. Raised in get_models() when json.loads() fails on the raw environment value. The offending value is embedded in the message, making the syntax error easy to spot.

Source

Thrown at g4f/Provider/needs_auth/Azure.py:49

        }
    }
    api_keys: dict[str, str] = {}
    failed: dict[str, int] = {}

    @classmethod
    def get_models(cls, api_key: str = None, **kwargs) -> list[str]:
        api_keys = os.environ.get("AZURE_API_KEYS")
        if api_keys:
            try:
                cls.api_keys = json.loads(api_keys)
            except json.JSONDecodeError:
                raise ValueError(f"Invalid AZURE_API_KEYS environment variable")
        routes = os.environ.get("AZURE_ROUTES")
        if routes:
            try:
                routes = json.loads(routes)
            except json.JSONDecodeError:
                raise ValueError(
                    f"Invalid AZURE_ROUTES environment variable format: {routes}"
                )
            cls.routes = routes
        if cls.routes:
            if cls.live == 0 and cls.api_keys:
                cls.live += 1
            return list(cls.routes.keys())
        return super().get_models(api_key=api_key, **kwargs)

    @classmethod
    async def create_async_generator(
        cls,
        model: str,
        messages: Messages,
        stream: bool = True,
        media: MediaListType = None,
        api_key: str = None,
        api_endpoint: str = None,

View on GitHub (pinned to 973504e177)

Solutions

  1. Use strict JSON with double-quoted keys and values: AZURE_ROUTES='{"gpt-4o": "https://res.openai.azure.com/openai/deployments/gpt-4o"}'.
  2. Run echo "$AZURE_ROUTES" | python -m json.tool to pinpoint the syntax error.
  3. Keep routes and keys env vars in one place (.env loaded by the app) so they are validated together.

Example fix

# before
export AZURE_ROUTES="{'gpt-4o': 'https://res.openai.azure.com/...'}"

# after
export AZURE_ROUTES='{"gpt-4o": "https://res.openai.azure.com/openai/deployments/gpt-4o"}'
Defensive patterns

Strategy: validation

Validate before calling

import json, os

def validate_azure_routes() -> dict:
    raw = os.environ.get("AZURE_ROUTES")
    if not raw:
        return {}
    parsed = json.loads(raw)  # fail fast at startup with clear error
    assert isinstance(parsed, dict) and all(isinstance(v, str) for v in parsed.values()), \
        "AZURE_ROUTES must be a JSON object of model -> endpoint URL strings"
    return parsed

Type guard

def is_valid_routes_env(raw: str | None) -> bool:
    """True when AZURE_ROUTES is absent or a JSON object of URL strings."""
    if not raw:
        return True
    try:
        parsed = json.loads(raw)
    except json.JSONDecodeError:
        return False
    return isinstance(parsed, dict) and all(isinstance(v, str) for v in parsed.values())

Try / catch

try:
    models = Azure.get_models()
except ValueError as e:
    if "AZURE_ROUTES" in str(e):
        # message embeds the bad value: fix JSON syntax, restart process
        raise

Prevention

When it happens

Trigger: Setting AZURE_ROUTES to anything non-JSON (a bare URL, unquoted keys, single-quoted dict) and invoking get_models() or create_async_generator without an explicit api_endpoint.

Common situations: Copied a Python-dict-style routes mapping into a .env file; YAML-style config pasted as env; missing closing brace after hand-editing routes.

Related errors


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/4b391f5079a76f92. Report an issue: GitHub.