{"record":{"id":"a15895a9af0026b5","repo":"HKUDS/Vibe-Trading","slug":"tushare-token-is-not-configured","errorCode":null,"errorMessage":"TUSHARE_TOKEN is not configured","messagePattern":"TUSHARE_TOKEN is not configured","errorType":"exception","errorClass":"TushareFallbackUnavailable","httpStatus":null,"severity":"error","filePath":"agent/src/tools/tushare_fallbacks.py","lineNumber":25,"sourceCode":"\nfrom __future__ import annotations\n\nfrom datetime import date, timedelta\nfrom typing import Any\n\nfrom src.config.accessor import get_env_config\n\n_TUSHARE_TOKEN_PLACEHOLDERS = {\"\", \"your-tushare-token\"}\n\n\nclass TushareFallbackUnavailable(RuntimeError):\n    \"\"\"Raised when the optional Tushare fallback cannot be used.\"\"\"\n\n\ndef _pro_api() -> Any:\n    token = get_env_config().data.tushare_token.strip()\n    if token in _TUSHARE_TOKEN_PLACEHOLDERS:\n        raise TushareFallbackUnavailable(\"TUSHARE_TOKEN is not configured\")\n    try:\n        import tushare as ts\n    except Exception as exc:  # noqa: BLE001 - import errors vary by install\n        raise TushareFallbackUnavailable(f\"tushare import failed: {exc}\") from exc\n    return ts.pro_api(token)\n\n\ndef _records(frame: Any) -> list[dict[str, Any]]:\n    if frame is None:\n        return []\n    if bool(getattr(frame, \"empty\", False)):\n        return []\n    if hasattr(frame, \"to_dict\"):\n        rows = frame.to_dict(\"records\")\n        return [row for row in rows if isinstance(row, dict)]\n    if isinstance(frame, list):\n        return [row for row in frame if isinstance(row, dict)]\n    return []","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/tushare_fallbacks.py#L7-L43","documentation":"This error is raised by _pro_api in agent/src/tools/tushare_fallbacks.py when the configured TUSHARE_TOKEN is empty or a placeholder value. The Tushare fallback data source requires a valid API token before it can construct the pro_api client. Without it, all fallback fetchers (fund flow, dragon tiger, northbound flow, margin trading) are unusable.","triggerScenarios":"Calling fetch_fund_flow, fetch_dragon_tiger, fetch_northbound_flow, or fetch_margin_trading when get_env_config().data.tushare_token is unset, blank, or one of the placeholder sentinel values in _TUSHARE_TOKEN_PLACEHOLDERS (e.g. the literal 'TUSHARE_TOKEN' or 'your-token-here').","commonSituations":"Fresh clone without a .env file; CI environment missing the TUSHARE_TOKEN secret; template config copied with placeholder token left in place; deployment where the env var name is misspelled or scoped to a different process.","solutions":["Set TUSHARE_TOKEN to a real token from tushare.pro in your environment / .env config","Remove any placeholder value (do not leave 'TUSHARE_TOKEN' or similar) — the code treats placeholders as unset","Verify with a quick check that get_env_config().data.tushare_token returns a non-empty, non-placeholder string before calling fallback fetchers","Treat the failure as non-fatal: catch TushareFallbackUnavailable and degrade to the primary data source"],"exampleFix":"# before\nTUSHARE_TOKEN=TUSHARE_TOKEN\n\n# after\nTUSHARE_TOKEN=<real token from tushare.pro>","handlingStrategy":"validation","validationCode":"from agent.src.config import get_env_config  # adjust import to project layout\n\ndef tushare_ready() -> bool:\n    token = get_env_config().data.tushare_token.strip()\n    return bool(token) and token not in {'TUSHARE_TOKEN', 'your-token-here', 'changeme'}\n\nif not tushare_ready():\n    logger.warning('Tushare fallback disabled: TUSHARE_TOKEN not set')","typeGuard":null,"tryCatchPattern":"try:\n    data = fetch_fund_flow(sym, days=5)\nexcept TushareFallbackUnavailable as exc:\n    if 'TUSHARE_TOKEN' in str(exc):\n        logger.warning('fallback disabled: %s', exc)\n        data = primary_source(sym, days=5)\n    else:\n        raise","preventionTips":["Set TUSHARE_TOKEN in the deployment environment, not just locally","Add a startup assertion that the token is non-empty and not a placeholder","Treat the Tushare fallback as optional: always pair it with a primary data source"],"tags":["tushare","config","env-var","api-token","fallback"],"backgroundTag":"missing-env-var","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}