{"record":{"id":"0a3ab34520cab556","repo":"xai-org/x-algorithm","slug":"wilyns-returned-no-entries-for-self-wily-path","errorCode":null,"errorMessage":"WilyNS returned no entries for {self._wily_path}","messagePattern":"WilyNS returned no entries for (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"grox/libs/wily_cli/http_client.py","lineNumber":59,"sourceCode":"    @staticmethod\n    def _encode_lookup_path(wily_path: str) -> str:\n        path = unquote(wily_path.lstrip(\"/\"))\n        return quote(path, safe=\"/:\")\n\n    async def _resolve_wilyns(self) -> str:\n        path = self._encode_lookup_path(self._wily_path)\n        wilyns_url = f\"https://wilyns-{self._zone}.twitter.biz\"\n        context = f\"/p/static/{self._zone}/{self._role}/{self._client_name}/0/{int(time.time())}\"\n        async with httpx.AsyncClient() as tmp:\n            resp = await tmp.get(\n                f\"{wilyns_url}/lookups/{path}\",\n                params={\"context\": context},\n                timeout=10.0,\n            )\n            resp.raise_for_status()\n            entries = resp.json().get(\"entries\", [])\n            if not entries:\n                raise RuntimeError(f\"WilyNS returned no entries for {self._wily_path}\")\n            entry = random.choice(entries)\n            url = f\"http://{entry['addr']}:{entry['port']}\"\n            return url\n\n    async def _resolve(self) -> str:\n        if self._static_url:\n            logger.info(\"%s: using static URL %s\", self._name, self._static_url)\n            return self._static_url\n        url = await self._resolve_wilyns()\n        logger.info(\n            \"%s: resolved via WilyNS %s -> %s\", self._name, self._wily_path, url\n        )\n        return url\n\n    async def _build_client(self):\n        old_client = self._client\n        self._base_url = await self._resolve()\n        self._client = httpx.AsyncClient(base_url=self._base_url, timeout=self._timeout)","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/grox/libs/wily_cli/http_client.py#L41-L77","documentation":"When resolving via WilyNS, the client GETs the discovery endpoint and expects a JSON 'entries' list of {addr, port} records; it randomly picks one. If entries is empty, there is no instance to route to and it raises RuntimeError naming the wily_path. The HTTP call itself succeeded — the service simply has no registered instances.","triggerScenarios":"Calling an endpoint on a WilyHttpClient constructed with wily_path where WilyNS returns 200 with {\"entries\": []} — the service exists as a path but has zero live/registered instances.","commonSituations":"All instances of the target service are down or scaled to zero; service just deployed and not yet registered; environment/namespace mismatch so you query a path with no instances; stale wily_path typo that still resolves but to an empty pool.","solutions":["Verify the target service has running instances and they are registered in WilyNS (check the service's health/registration).","Double-check the wily_path string (role/env segment typos lead to empty pools).","Retry after instances come up; treat empty entries as transient and back off.","If the service is expected to exist, fall back to static_url addressing while discovery repopulates."],"exampleFix":"# before\nclient = WilyHttpClient(wily_path='prod/ads/recs')\nurl = await client._resolve()  # RuntimeError: no entries\n\n# after\nclient = WilyHttpClient(\n    wily_path='prod/ads/recs',\n    static_url='http://recs-fallback:8080',  # optional fallback path\n)","handlingStrategy":"retry","validationCode":"# pre-check instance availability if a discovery query helper exists\nentries = await wilyns_lookup(wily_path)\nif not entries:\n    logger.warning('no instances for %s; will retry', wily_path)","typeGuard":null,"tryCatchPattern":"for delay in (1, 2, 5):\n    try:\n        resp = await client.get(path)\n        break\n    except RuntimeError as e:\n        if 'no entries' not in str(e):\n            raise\n        await asyncio.sleep(delay)\nelse:\n    raise RuntimeError(f'WilyNS pool stayed empty for {wily_path}')","preventionTips":["Health-check target services so empty pools are detected early","Keep a static_url fallback for critical dependencies","Alert when a discovery path returns zero instances persistently"],"tags":["service-discovery","wilyns","no-instances","routing"],"backgroundTag":"service-discovery-empty","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}