{"record":{"id":"ec5aab44416994e7","repo":"OpenBB-finance/OpenBB","slug":"category-category-not-found-available-categor","errorCode":null,"errorMessage":"Category '{category}' not found. Available categories: {', '.join(sorted(available))}","messagePattern":"Category '(.+?)' not found\\. Available categories: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py","lineNumber":635,"sourceCode":"        @mcp.tool(tags={\"admin\"})\n        async def available_tools(\n            category: Annotated[\n                str, Field(description=\"The category of tools to list\")\n            ],\n            subcategory: Annotated[\n                str | None,\n                Field(\n                    description=\"Optional subcategory to filter by. \"\n                    \"Use 'general' for tools directly under the category.\"\n                ),\n            ] = None,\n        ) -> list[ToolInfo]:\n            \"\"\"List tools in a specific category and subcategory.\"\"\"\n            cat_data = category_index.get_subcategories(category)\n\n            if cat_data is None:\n                available = list(category_index.get_categories().keys())\n                raise ValueError(\n                    f\"Category '{category}' not found. \"\n                    f\"Available categories: {', '.join(sorted(available))}\"\n                )\n\n            if subcategory:\n                names = category_index.get_subcategory_names(category, subcategory)\n                if not names:\n                    raise ValueError(\n                        f\"Subcategory '{subcategory}' not found in category '{category}'. \"\n                        f\"Available subcategories: {', '.join(sorted(cat_data.keys()))}\"\n                    )\n            else:\n                names = category_index.get_category_names(category)\n\n            # Resolve active state from FastMCP's live tool list\n            active_tools = await mcp.list_tools()\n            active_names = {t.name for t in active_tools}\n","sourceCodeStart":617,"sourceCodeEnd":653,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py#L617-L653","documentation":"Raised by the OpenBB MCP server's list-tools-by-category tool when the requested category string does not exist in the server's category index. The index is built from the OpenBB router tree, so a category only exists if the corresponding extension is installed and loaded. The error message lists all valid categories to guide correction.","triggerScenarios":"Calling list_category_tools(category=\"fixedincome\") when the fixedincome extension is not installed/enabled; passing a category name with different casing, whitespace, or a plural/singular mismatch (e.g. 'stocks' vs 'stock'); referencing a category from an older OpenBB version after a rename.","commonSituations":"MCP client (Claude, etc.) hardcoding a category name that no longer exists; partial openbb installation where only some extensions are installed; version upgrades that renamed router categories.","solutions":["Read the error message: it enumerates the available categories; use one of those exact strings.","Install/enable the extension that provides the missing category (e.g. pip install openbb-fixedincome) and restart the MCP server.","Call the category-listing tool first and derive names dynamically instead of hardcoding.","Check exact casing and spelling — category keys are matched literally, not case-insensitively."],"exampleFix":"# before\ntools = await list_category_tools(category=\"FixedIncome\")\n\n# after\ncats = await list_categories()  # discover valid keys first\ntools = await list_category_tools(category=cats[\"fixedincome\"] if \"fixedincome\" in cats else sorted(cats)[0])","handlingStrategy":"validation","validationCode":"async def safe_list_category_tools(mcp_client, category: str):\n    cats = (await mcp_client.call_tool(\"list_categories\", {})).result\n    if category not in {c[\"name\"] for c in cats}:\n        raise KeyError(f\"unknown category {category!r}; known: {sorted(c['name'] for c in cats)}\")\n    return await mcp_client.call_tool(\"list_category_tools\", {\"category\": category})","typeGuard":"def is_known_category(category: str, known: set[str]) -> bool:\n    return isinstance(category, str) and category in known","tryCatchPattern":"try:\n    tools = await list_category_tools(category=cat)\nexcept ValueError as e:\n    if \"not found. Available categories:\" in str(e):\n        available = str(e).split(\"Available categories:\")[-1]\n        cat = choose(available)  # re-ask user / pick programmatically\n        tools = await list_category_tools(category=cat)\n    else:\n        raise","preventionTips":["Always enumerate categories dynamically instead of hardcoding names.","Validate user-supplied category strings against the listing tool output.","Keep MCP client prompts in sync with the installed OpenBB extensions."],"tags":["openbb","mcp","mcp-server","validation"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}