unslothai/unsloth · warning · HTTPException
url must not be empty
Error message
url must not be empty
What it means
400 from _validate_url when the MCP server 'url' field is empty or only whitespace after stripping. The field is overloaded: it holds either an http(s) URL or (when stdio is enabled) a local command, but it may not be blank in either mode.
Source
Thrown at studio/backend/routes/mcp_servers.py:65
router = APIRouter()
# Only a UI session may define a local command; API keys keep http(s) MCP.
# Annotated, not a Depends default: these routes are also called directly by the
# tests, where a Depends object is truthy and would read as "API key".
ViaApiKey = Annotated[bool, Depends(authenticated_via_api_key)]
def _looks_like_command(value: str) -> bool:
"""Whitespace is a one-way signal: a URL can't hold an unencoded space, so
a value with whitespace is definitely a command. No whitespace proves
nothing (a lone token may be a single-arg command or a scheme-less URL)."""
return any(ch.isspace() for ch in value)
def _validate_url(url: str) -> str:
trimmed = (url or "").strip()
if not trimmed:
raise HTTPException(status_code = 400, detail = "url must not be empty")
# When stdio is enabled, a non-HTTP value is a local command (reuses this
# field so stdio servers ride existing CRUD/storage).
if stdio_mcp_enabled() and is_stdio(trimmed):
try:
parts = parse_stdio_command(trimmed)
except ValueError as exc:
raise log_and_http_error(
exc,
400,
"Invalid command. Check quoting and try again.",
event = "mcp_servers.invalid_command",
log = logger,
)
if not parts or not parts[0].strip():
raise HTTPException(status_code = 400, detail = "command must not be empty")
if "://" in parts[0]:
# A URL-scheme first token is a mistyped URL, not a command. Reject
# cleanly instead of exec-ing it (mirrors the frontend check).View on GitHub (pinned to 203007d190)
Solutions
- Provide a non-blank url: an http(s):// URL or, when stdio is enabled, a local command string.
- Trim input client-side and disable submit while the field is empty.
- For updates, omit the 'url' key entirely instead of sending an empty string when you don't intend to change it.
Example fix
// before
await api.post('/api/mcp-servers/', {display_name: 'fs', url: ''});
// after
const url = urlInput.trim();
if (!url) throw new Error('URL is required');
await api.post('/api/mcp-servers/', {display_name: 'fs', url}); Defensive patterns
Strategy: validation
Validate before calling
const url = (payload.url ?? '').trim();
if (!url) throw new Error('MCP url is required'); Type guard
function hasNonEmptyUrl(p) { return typeof p.url === 'string' && p.url.trim().length > 0; } Prevention
- Trim and require a non-empty url in the form before enabling submit.
- Omit 'url' from PUT bodies when not changing it.
When it happens
Trigger: POST /api/mcp-servers/ (create) or PUT /{server_id} with url set to '', ' ', or null coerced to empty; also PUT that includes 'url' in the payload with an empty value.
Common situations: Frontend form submitted before the user typed an address, JSON built with a default empty string, or an update payload that accidentally includes url:'' alongside other fields.
Related errors
- Enter an http(s):// URL, or a local command whose first toke
- MCP server address must start with http:// or https:// (for
- url is missing a host
- command must not be empty
- is_enabled must be true or false
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/62fbaf222d433c13.
Report an issue: GitHub.