open-webui/open-webui · warning · HTTPException

Terminal server URL is required

Error message

Terminal server URL is required

What it means

POST /terminal_servers/verify (admin-only) strips the submitted url and rejects an empty string with 400 'Terminal server URL is required'. Pure input validation before any network call is attempted.

Source

Thrown at backend/open_webui/routers/configs.py:361

        subject_type='config',
        data={'count': len(connections)},
    )
    return {'TERMINAL_SERVER_CONNECTIONS': connections}


@router.post('/terminal_servers/verify')
async def verify_terminal_server_connection(
    request: Request, form_data: TerminalServerConnection, user=Depends(get_admin_user)
):
    """
    Verify the connection to a terminal server by detecting its type.

    Tries GET {url}/api/v1/policies (orchestrator) then GET {url}/api/config
    (plain terminal).  Returns ``{status: true, type: "orchestrator"|"terminal"}``.
    """
    base_url = (form_data.url or '').rstrip('/')
    if not base_url:
        raise HTTPException(status_code=400, detail='Terminal server URL is required')

    headers = {}
    if form_data.auth_type == 'bearer' and form_data.key:
        headers.update(bearer_auth_header(form_data.key))

    try:
        async with aiohttp.ClientSession(
            trust_env=True,
            timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT),
        ) as session:
            # Orchestrators expose a policies API; plain terminals don't.
            try:
                async with session.get(
                    f'{base_url}/api/v1/policies', headers=headers, ssl=AIOHTTP_CLIENT_SESSION_SSL
                ) as resp:
                    if resp.ok:
                        return {'status': True, 'type': 'orchestrator'}
            except Exception:

View on GitHub (pinned to 01f4282f1f)

Solutions

  1. Provide a non-empty base URL, e.g. 'https://terminal.example.com' (no trailing path required; trailing slash is trimmed).
  2. Client-side: require the field before enabling submit.
  3. If the value comes from config/env, default it or fail the pipeline earlier with a clear message.

Example fix

// before
await api.post('/configs/terminal_servers/verify', { url: '' });

// after
if (!url.trim()) throw new Error('Terminal server URL is required');
await api.post('/configs/terminal_servers/verify', { url: url.trim() });
Defensive patterns

Strategy: validation

Validate before calling

if (!form.url || !form.url.trim()) throw new Error('Terminal server URL is required');

Type guard

function isNonEmptyUrl(u: unknown): u is string { return typeof u === 'string' && u.trim().length > 0 && u.trim() !== '/'; }

Prevention

When it happens

Trigger: Submitting the verify form with url: '', url: null coerced after strip, or a url consisting only of whitespace/slashes (rstrip('/') reduces it to '').

Common situations: Admin UI form submitted before the URL field was filled; config automation passing an unset environment-derived value that arrives as empty string.

Related errors


AI-assisted analysis of open-webui/open-webui@01f4282f1f (2026-08-14). Data as JSON: /api/errors/60c74c36a781d6a2. Report an issue: GitHub.