JuliusBrussee/caveman · error · MiddlewareError
invalid_endpoint
invalid_endpoint
Error message
invalid_endpoint
What it means
The middleware runtime constructor validates the endpoint URL strictly: scheme must be http/https, hostname present, no credentials/query/fragment, and path must be empty or "/". Any other URL shape raises MiddlewareError("invalid_endpoint") at construction time, before any network I/O.
Solutions
- Pass a bare origin: scheme + host + optional port only, e.g. "http://127.0.0.1:8080" or "https://proxy.example.com"
- Move any path/query into request configuration elsewhere — the runtime only accepts "" or "/" as path
- Remove userinfo (user:pass@) from the URL; supply credentials via headers/tokens instead
- Pre-validate with urllib.parse.urlsplit before constructing
Example fix
// before Runtime(endpoint="http://localhost:8080/api/v1?key=abc") // after Runtime(endpoint="http://localhost:8080") # bare origin; no path, query, or credentials
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlsplit
def valid_endpoint(endpoint: str) -> bool:
u = urlsplit(endpoint)
return (u.scheme in ('http', 'https') and bool(u.hostname)
and not u.username and not u.password
and not u.query and not u.fragment
and u.path in ('', '/')) Type guard
def is_bare_origin(endpoint: object) -> bool:
if not isinstance(endpoint, str):
return False
from urllib.parse import urlsplit
u = urlsplit(endpoint)
return (u.scheme in ('http', 'https') and bool(u.hostname)
and not (u.username or u.password or u.query or u.fragment)
and u.path in ('', '/')) Try / catch
try:
runtime = Runtime(endpoint=ep)
except MiddlewareError as e:
if str(e) == 'invalid_endpoint':
raise ConfigError(f'endpoint must be a bare http(s) origin, got {ep!r}') from e
raise Prevention
- Pass only scheme://host[:port] — no path, query, fragment, or credentials
- Validate endpoints with urlsplit in your config loader before constructing the runtime
- Keep path/version prefixes in the application layer, not the endpoint
- Strip credentials from URLs and use token/header configuration instead
When it happens
Trigger: Passing endpoints like "caveman://...", "http://host/base/path", "https://user:pass@host", URLs with ?query or #fragment, or an empty/unparsable endpoint string.
Common situations: Appending a base path (e.g. "http://localhost:8080/api/v1") because other HTTP clients allow it; leaving a template placeholder unfilled; including credentials in the URL out of habit.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Configure exact POST paths and native LLM protocols
- invalid_configuration
- invalid_endpoint
- must be an absolute http(s) URL
- must be an absolute http(s) URL without credentials
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/17009efa0e3d655c.
Report an issue: GitHub.
Appendix: source
Thrown at packages/sdk/python/caveman_cloud/middleware/runtime.py:67
return PreflightReport(1, "disabled" if reason == "disabled" else "ready" if reason in ("ready", "record_only") else "unavailable",
reason, mode, caps.get("mode"), caps.get("runtime_build") if validate.token(caps.get("runtime_build")) else None,
caps.get("policy_revision"), caps.get("persistent"), caps.get("recovery"), PREFLIGHT_ACTIONS[reason])
def _json(value: Any) -> str:
return json.dumps(value, ensure_ascii=False, separators=(",", ":"), allow_nan=False)
class MiddlewareRuntime:
def __init__(self, *, endpoint: str = "http://127.0.0.1:8787", token: str | None = None,
allow_remote_content: bool = False, mode: str = "compress", deadline_ms: int = 100,
retrieve_deadline_ms: int = 5000,
strict: bool = False, on_diagnostic: Callable[[dict], None] | None = None,
on_report: Callable[[CallReport], None] | None = None):
url = urlsplit(endpoint)
local = url.hostname in ("127.0.0.1", "::1", "localhost")
if url.scheme not in ("http", "https") or not url.hostname or url.username or url.password or url.query or url.fragment or url.path not in ("", "/"):
raise MiddlewareError("invalid_endpoint")
if not local and (not allow_remote_content or url.scheme != "https"):
raise MiddlewareError("remote_content_not_enabled")
if type(deadline_ms) is not int or deadline_ms <= 0 or mode not in ("off", "record", "compress"):
raise MiddlewareError("invalid_configuration")
# A model asking to see an original is waiting on a page of stored text,
# not on the optimizer in front of a provider call. Separate budget.
if type(retrieve_deadline_ms) is not int or retrieve_deadline_ms <= 0:
raise MiddlewareError("invalid_configuration")
self.endpoint = f"{url.scheme}://{url.netloc}"
self.mode, self.deadline_ms, self.strict = mode, deadline_ms, strict
self.retrieve_deadline_ms = retrieve_deadline_ms
self._token, self._diagnostic = token, on_diagnostic
self._report_sink, self._last_report = on_report, None
self._url = url
self._connections: set[http.client.HTTPConnection] = set()
self._caps: dict | None = None
self._bindings: weakref.WeakKeyDictionary[RecoveryBinding, tuple] = weakref.WeakKeyDictionary()
self._lock = threading.RLock()View on GitHub (pinned to 3ee70a1026)