{"record":{"id":"74082a606168fdf0","repo":"JuliusBrussee/caveman","slug":"runtime-unavailable-74082a","errorCode":"runtime_unavailable","errorMessage":"runtime_unavailable","messagePattern":"runtime_unavailable","errorType":"error_code","errorClass":"MiddlewareError","httpStatus":null,"severity":"error","filePath":"packages/sdk/python/caveman_cloud/middleware/runtime.py","lineNumber":402,"sourceCode":"            bound()\n            with connection.getresponse() as response:\n                if 300 <= response.status < 400:\n                    raise MiddlewareError(\"redirect_refused\")\n                content = bytearray()\n                while True:\n                    bound()\n                    # read1 plus the remaining socket deadline bounds slow,\n                    # chunked bodies without buffering beyond the response cap.\n                    part = response.read1(min(65536, (4 << 20) + 1 - len(content)))\n                    if not part:\n                        break\n                    content.extend(part)\n                    if len(content) > 4 << 20:\n                        raise MiddlewareError(\"payload_limit\")\n                data = json.loads(content.decode(\"utf-8\"))\n                if not 200 <= response.status < 300:\n                    code = data.get(\"error\", {}).get(\"code\") if isinstance(data, dict) else None\n                    raise MiddlewareError(code if validate.token(code) else \"runtime_unavailable\")\n                return data\n        finally:\n            connection.close()\n            with self._lock:\n                self._connections.discard(connection)\n","sourceCodeStart":384,"sourceCodeEnd":408,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/sdk/python/caveman_cloud/middleware/runtime.py#L384-L408","documentation":"MiddlewareError raised by _http as a fallback when the middleware returns a non-2xx status and either the body is not JSON, is not a dict, or its error.code is missing/invalid (fails validate.token). It means the server failed, but the client could not extract a more specific error code.","triggerScenarios":"Any of ready()/optimize()/retrieve()/observe()/delete_session() hitting an endpoint returning 4xx/5xx with an unparseable body: HTML error page from a proxy, empty 502 from a crashed gateway, or JSON whose error.code is not a valid token.","commonSituations":"Middleware process down (502/503 from reverse proxy); wrong port hitting a different service; TLS-terminating proxy emitting HTML error pages; middleware version returning an error shape the SDK doesn't expect.","solutions":["Check the middleware service is running and reachable (curl -i the endpoint) and that the URL/port points at the middleware, not a proxy UI","Inspect middleware logs for the failing request to find the real status/cause","Upgrade the SDK and middleware together so error response shapes match the expected {\"error\":{\"code\":...}} contract","Retry after fixing infrastructure; this error is usually environmental, not a client bug"],"exampleFix":"# before (service down)\nclient.ready()  # MiddlewareError: runtime_unavailable (502 HTML from nginx)\n# after\nsubprocess.run([\"systemctl\", \"start\", \"caveman-middleware\"])  # then retry client.ready()","handlingStrategy":"retry","validationCode":"def middleware_up(endpoint):\n    import urllib.request\n    try:\n        with urllib.request.urlopen(endpoint, timeout=5) as r:\n            return r.status < 500\n    except Exception:\n        return False","typeGuard":"def has_valid_error_code(body) -> bool:\n    return isinstance(body, dict) and isinstance(body.get(\"error\", {}).get(\"code\"), str) and bool(body[\"error\"][\"code\"])","tryCatchPattern":"for attempt in range(3):\n    try:\n        return client.ready()\n    except MiddlewareError as e:\n        if e.args[0] == \"runtime_unavailable\" and attempt < 2:\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Supervise the middleware process (systemd/k8s) so it doesn't silently die","Point the SDK at the middleware directly, not through a proxy that emits HTML error pages","Keep SDK and middleware versions in lockstep so error payloads match the expected shape","Alert on 5xx rates from the middleware endpoint"],"tags":["network","http","availability","python"],"backgroundTag":"http-error-response","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}