JuliusBrussee/caveman · error · MiddlewareError

invalid_configuration

invalid_configuration

Error message

invalid_configuration

What it means

The constructor enforces typed, sane configuration: deadline_ms must be a positive int and mode must be exactly one of "off", "record", "compress". Anything else — floats, strings for deadline, unknown mode names — raises MiddlewareError("invalid_configuration").

Solutions

  1. Pass deadline_ms as a strict positive int (e.g. int(os.environ["DEADLINE_MS"]))
  2. Use exactly "off", "record", or "compress" for mode
  3. Validate config at load time: type(x) is int and x > 0 and mode in {...}
  4. Catch MiddlewareError("invalid_configuration") during startup to fail fast with context

Example fix

// before
Runtime(endpoint=ep, deadline_ms="5000", mode="compress-mode")
// after
Runtime(endpoint=ep, deadline_ms=int("5000"), mode="compress")
Defensive patterns

Strategy: validation

Validate before calling

assert type(deadline_ms) is int and deadline_ms > 0, 'deadline_ms must be positive int'
assert mode in ('off', 'record', 'compress'), f'invalid mode: {mode!r}'

Type guard

def valid_runtime_config(deadline_ms: object, mode: object) -> bool:
    return (type(deadline_ms) is int and deadline_ms > 0
            and mode in ('off', 'record', 'compress'))

Try / catch

try:
    runtime = Runtime(endpoint=ep, deadline_ms=deadline_ms, mode=mode)
except MiddlewareError as e:
    if str(e) == 'invalid_configuration':
        raise ConfigError(f'deadline_ms={deadline_ms!r} must be positive int; mode={mode!r} in off|record|compress') from e
    raise

Prevention

When it happens

Trigger: Passing deadline_ms=5000.0 (float), deadline_ms=0 or negative, mode=" Off", mode="compression", or mode=None.

Common situations: Reading the deadline from an env var or YAML without int conversion (getting str/float); renaming modes based on guessed spelling ("compressed", "off mode"); typos after a config refactor.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/f736c6df4c3af9eb. Report an issue: GitHub.

Appendix: source

Thrown at packages/sdk/python/caveman_cloud/middleware/runtime.py:71

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()
        self._slots = threading.BoundedSemaphore(16)
        self._closed = False
        self._failures = 0
        self._open_until = 0.0

View on GitHub (pinned to 3ee70a1026)