{"record":{"id":"fa6d1bb76dacb6f8","repo":"HKUDS/Vibe-Trading","slug":"unknown-zoo-zoo-r-expected-one-of-sorted-vali","errorCode":null,"errorMessage":"unknown zoo {zoo!r}; expected one of {sorted(_VALID_ZOOS)}","messagePattern":"unknown zoo (.+?); expected one of (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"agent/src/api/alpha_routes.py","lineNumber":392,"sourceCode":"        if require_auth is None:\n            require_auth = host.require_auth\n        if require_event_stream_auth is None:\n            require_event_stream_auth = host.require_event_stream_auth\n\n    # -----------------------------------------------------------------------\n    # GET /alpha/list\n    # -----------------------------------------------------------------------\n\n    @app.get(\"/alpha/list\", dependencies=[Depends(require_auth)])\n    async def list_alphas(\n        zoo: str | None = Query(None, max_length=64),\n        theme: str | None = Query(None, max_length=64),\n        universe: str | None = Query(None, max_length=64),\n        limit: int = Query(100, ge=1, le=1000),\n    ) -> dict[str, Any]:\n        \"\"\"List alphas, optionally filtered by zoo / theme / universe.\"\"\"\n        if zoo is not None and zoo not in _VALID_ZOOS:\n            raise HTTPException(\n                status_code=400,\n                detail=f\"unknown zoo {zoo!r}; expected one of {sorted(_VALID_ZOOS)}\",\n            )\n        if theme is not None and theme not in _VALID_THEMES:\n            raise HTTPException(\n                status_code=400,\n                detail=f\"unknown theme {theme!r}; expected one of {sorted(_VALID_THEMES)}\",\n            )\n        if universe is not None:\n            _ALIAS = {\"csi300\": \"equity_cn\", \"sp500\": \"equity_us\", \"btc-usdt\": \"crypto\"}\n            universe = _ALIAS.get(universe, universe)\n        if universe is not None and universe not in _VALID_UNIVERSES:\n            raise HTTPException(\n                status_code=400,\n                detail=f\"unknown universe {universe!r}; expected one of {sorted(_VALID_UNIVERSES)}\",\n            )\n\n        from src.factors.registry import get_default_registry","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/api/alpha_routes.py#L374-L410","documentation":"install_connector validates the connector directory, then copies it into the shared plugin root under the connector name. If root/<connector> already exists it raises ValueError, enforcing one installed copy per connector id.","triggerScenarios":"Running connector install twice without uninstalling; installing a second variant of the same connector id from a different source directory.","commonSituations":"Re-running an install script after editing the connector source — developers expect overwrite but get an error; CI pipelines installing repeatedly into a persistent plugin root.","solutions":["Uninstall/remove the existing directory under plugin_root()/<connector> first, then reinstall","Or overwrite manually: remove the target dir and re-run install so the edited source is copied in","Guard install scripts with an existence check before calling install_connector"],"exampleFix":"# before\ninstall_connector(Path(\"./acme-broker\"))  # ValueError: already installed\n\n# after\nfrom src.trading.plugin_scaffold import install_connector, plugin_root\nimport shutil\ntarget = plugin_root() / \"acme-broker\"\nif target.exists():\n    shutil.rmtree(target)\ninstall_connector(Path(\"./acme-broker\"))","handlingStrategy":"validation","validationCode":"from src.trading.plugin_scaffold import plugin_root\nfrom src.trading.local_plugins import validate_connector\n\ndef install_is_clean(directory) -> bool:\n    plugin = validate_connector(directory)\n    return not (plugin_root() / plugin.profile.connector).exists()","typeGuard":null,"tryCatchPattern":"try:\n    install_connector(directory)\nexcept ValueError as e:\n    if \"already installed\" in str(e):\n        target = plugin_root() / validate_connector(directory).profile.connector\n        shutil.rmtree(target)\n        install_connector(directory)  # refresh install\n    else:\n        raise","preventionTips":["Wrap install in scripts with an exists-check for idempotency","Treat reinstall as uninstall+install, never assume overwrite","Version connectors by id if you need parallel variants"],"tags":["install","filesystem","already-exists","plugin-system"],"backgroundTag":"plugin-already-installed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}