{"record":{"id":"0ac0ed73c770cfbc","repo":"HKUDS/DeepTutor","slug":"ima-accepts-at-most-max-detail-ids-knowledge-bas","errorCode":null,"errorMessage":"IMA accepts at most {MAX_DETAIL_IDS} knowledge base IDs per request.","messagePattern":"IMA accepts at most (.+?) knowledge base IDs per request\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/rag/pipelines/ima/client.py","lineNumber":310,"sourceCode":"                }\n            )\n        return {\n            \"knowledge_bases\": knowledge_bases,\n            \"next_cursor\": cursor_state.next_cursor,\n            \"is_end\": cursor_state.is_end,\n        }\n\n    async def get_knowledge_bases(self, ids: list[str]) -> dict[str, dict[str, Any]]:\n        \"\"\"Return details for at most :data:`MAX_DETAIL_IDS` knowledge base ids.\"\"\"\n        normalized: list[str] = []\n        for item in ids:\n            kb_id = str(item or \"\").strip()\n            if kb_id and kb_id not in normalized:\n                normalized.append(kb_id)\n        if not normalized:\n            return {}\n        if len(normalized) > MAX_DETAIL_IDS:\n            raise ValueError(\n                f\"IMA accepts at most {MAX_DETAIL_IDS} knowledge base IDs per request.\"\n            )\n\n        data = await self._wire.post(\"get_knowledge_base\", {\"ids\": normalized})\n        infos = data.get(\"infos\")\n        if not isinstance(infos, dict):\n            return {}\n        return {str(kb_id): info for kb_id, info in infos.items() if isinstance(info, dict)}\n\n    async def get_knowledge_base(self) -> dict[str, Any]:\n        \"\"\"Return the bound knowledge base's info, or ``{}`` when unknown.\n\n        Doubles as the credential check: bad credentials raise\n        :class:`ImaAuthError`, while a well-formed but unknown id simply yields\n        no entry for it.\n        \"\"\"\n        kb_id = self._config.knowledge_base_id\n        return (await self.get_knowledge_bases([kb_id])).get(kb_id, {})","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/rag/pipelines/ima/client.py#L292-L328","documentation":"ValueError from IMA client get_knowledge_bases: after normalization/dedup, more than MAX_DETAIL_IDS (20) knowledge base IDs were passed to the detail lookup, exceeding the endpoint's per-request ID cap.","triggerScenarios":"Calling get_knowledge_bases with >20 IDs directly, or via search_knowledge_bases / get_knowledge_base when the search result set resolves to more than 20 IDs.","commonSituations":"Listing a large tenant with many KBs and then fetching details for all of them; pagination logic that assumes unbounded ID lookups.","solutions":["Batch IDs into groups of ≤20 and merge the returned info dicts.","Request only the specific KBs you need to display.","Cache detail lookups to avoid re-fetching wide ID sets."],"exampleFix":"# before\ninfos = await client.get_knowledge_bases(all_ids)  # 50 ids\n# after\ninfos = {}\nfor chunk in batched(all_ids, 20):\n    infos.update(await client.get_knowledge_bases(list(chunk)))","handlingStrategy":"validation","validationCode":"normalized = dedupe(kb_ids)\nif len(normalized) > MAX_DETAIL_IDS:\n    normalized = normalized[:MAX_DETAIL_IDS]  # or batch","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wrap get_knowledge_bases in a batching helper capped at 20 IDs.","Prefer targeted lookups over wide ID lists."],"tags":["ima","batch-size","pagination","input-validation"],"backgroundTag":"request-batch-limit-exceeded","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}