{"record":{"id":"361db293ef9c1bc4","repo":"run-llama/llama_index","slug":"unexpected-type-type-query","errorCode":null,"errorMessage":"Unexpected type: {type(query)}","messagePattern":"Unexpected type: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/base/base_selector.py","lineNumber":69,"sourceCode":"SelectorResult = MultiSelection\n\n\ndef _wrap_choice(choice: MetadataType) -> ToolMetadata:\n    if isinstance(choice, ToolMetadata):\n        return choice\n    elif isinstance(choice, str):\n        return ToolMetadata(description=choice)\n    else:\n        raise ValueError(f\"Unexpected type: {type(choice)}\")\n\n\ndef _wrap_query(query: QueryType) -> QueryBundle:\n    if isinstance(query, QueryBundle):\n        return query\n    elif isinstance(query, str):\n        return QueryBundle(query_str=query)\n    else:\n        raise ValueError(f\"Unexpected type: {type(query)}\")\n\n\nclass BaseSelector(PromptMixin, DispatcherSpanMixin):\n    \"\"\"Base selector.\"\"\"\n\n    def _get_prompt_modules(self) -> PromptMixinType:\n        \"\"\"Get prompt sub-modules.\"\"\"\n        return {}\n\n    def select(\n        self, choices: Sequence[MetadataType], query: QueryType\n    ) -> SelectorResult:\n        metadatas = [_wrap_choice(choice) for choice in choices]\n        query_bundle = _wrap_query(query)\n        return self._select(choices=metadatas, query=query_bundle)\n\n    async def aselect(\n        self, choices: Sequence[MetadataType], query: QueryType","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/base/base_selector.py#L51-L87","documentation":"Raised by _wrap_query when the query argument to BaseSelector.select is neither a QueryBundle nor a str. The helper normalizes the query into a QueryBundle; any other type (int, dict, list, None) is rejected.","triggerScenarios":"Calling selector.select(choices=..., query=<non-str-non-QueryBundle>) such as query=123, query=None, or query=some_dict. Also happens when a wrapper passes through an unvalidated user input.","commonSituations":"Passing a raw user-supplied payload (e.g. from a web request body) straight into a router's selector without coercing to str; refactors that changed the query variable's type.","solutions":["Coerce the query to str before calling select (e.g. query=str(user_input)).","Or construct a QueryBundle explicitly: QueryBundle(query_str=...) when you also need extra fields (custom_embedding_str, metadata).","Add an input validation layer at your API boundary that rejects/normalizes non-string queries."],"exampleFix":"# before\nresult = selector.select(choices=choices, query=request.json[\"q\"])\n\n# after\nq = str(request.json[\"q\"])\nresult = selector.select(choices=choices, query=q)","handlingStrategy":"validation","validationCode":"if not isinstance(query, (str, QueryBundle)):\n    query = str(query)","typeGuard":"def is_valid_query(q: Any) -> bool:\n    return isinstance(q, (str, QueryBundle))","tryCatchPattern":null,"preventionTips":["Coerce external inputs to str before calling select.","Type-annotate your wrapper functions so mypy catches bad query types."],"tags":["llama-index","selector","type-validation","query"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}