{"record":{"id":"0b7fcd77d4729135","repo":"TauricResearch/TradingAgents","slug":"indicator-is-not-a-known-macro-alias-or-a-vali","errorCode":null,"errorMessage":"'{indicator}' is not a known macro alias or a valid FRED series ID. Use an alias (e.g. 'cpi', 'unemployment', '10y_treasury') or a raw FRED series ID (e.g. 'CPIAUCSL').","messagePattern":"'(.+?)' is not a known macro alias or a valid FRED series ID\\. Use an alias \\(e\\.g\\. 'cpi', 'unemployment', '10y_treasury'\\) or a raw FRED series ID \\(e\\.g\\. 'CPIAUCSL'\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tradingagents/dataflows/fred.py","lineNumber":110,"sourceCode":"    return api_key\n\n\ndef _resolve_series_id(indicator: str) -> str:\n    \"\"\"Map a friendly alias to a FRED series ID, or pass a raw ID through.\n\n    Raises ``ValueError`` when the input is neither a known alias nor a plausible\n    series ID — typically a descriptive phrase the LLM passed instead (e.g.\n    \"bank of japan rate\"). FRED IDs are short and alphanumeric, so this rejects\n    it up front with guidance rather than letting it 400 the API.\n    \"\"\"\n    key = indicator.strip().lower().replace(\" \", \"_\").replace(\"-\", \"_\")\n    if key in MACRO_SERIES:\n        return MACRO_SERIES[key]\n    candidate = indicator.strip().upper()\n    # FRED series IDs never contain whitespace and are short; reject anything\n    # else (a descriptive phrase the LLM passed) rather than 400ing the API.\n    if not candidate or len(candidate) > 30 or any(c.isspace() for c in candidate):\n        raise ValueError(\n            f\"'{indicator}' is not a known macro alias or a valid FRED series ID. \"\n            f\"Use an alias (e.g. 'cpi', 'unemployment', '10y_treasury') or a raw \"\n            f\"FRED series ID (e.g. 'CPIAUCSL').\"\n        )\n    return candidate\n\n\ndef _request(path: str, params: dict) -> dict:\n    \"\"\"GET a FRED endpoint, surfacing FRED's JSON error body on a bad request.\"\"\"\n    api_params = {**params, \"api_key\": get_api_key(), \"file_type\": \"json\"}\n    response = requests.get(\n        f\"{FRED_API_BASE}/{path}\", params=api_params, timeout=REQUEST_TIMEOUT\n    )\n    # FRED returns 400 with a JSON {\"error_message\": ...} for unknown series IDs\n    # or malformed params; turn that into a clear, actionable error.\n    if response.status_code == 400:\n        try:\n            message = response.json().get(\"error_message\", response.text)","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/TauricResearch/TradingAgents/blob/a33fd4c0f134485a43553a2c23a63cb14adbd88f/tradingagents/dataflows/fred.py#L92-L128","documentation":"Raised by _resolve_series_id() in tradingagents/dataflows/fred.py when the indicator argument is neither a known macro alias (keys of MACRO_SERIES like 'cpi', 'unemployment', '10y_treasury') nor a plausible raw FRED series ID: FRED IDs are uppercase, short (<= 30 chars), and contain no whitespace. It is a ValueError that fails fast with guidance instead of letting a malformed query 400 at the API.","triggerScenarios":"Passing natural-language phrases such as 'bank of japan rate', 'fed funds', or 'GDP growth rate'; passing lowercase raw IDs without uppercase normalization won't error (upper-cased), but spaces, >30-char strings, or empty strings do; passing a question sentence from an LLM tool call.","commonSituations":"LLM macro analyst emitting descriptive phrases instead of the documented aliases; users guessing series names; prompts not listing the accepted aliases; multi-word queries not yet mapped in MACRO_SERIES.","solutions":["Use a documented alias from MACRO_SERIES ('cpi', 'unemployment', '10y_treasury', etc.) — check fred.py's MACRO_SERIES dict for the exact set","Or pass a real FRED series ID (uppercase, no spaces, <= 30 chars), e.g. 'CPIAUCSL', 'FEDFUNDS', 'DGS10'","Extend MACRO_SERIES with a new alias -> series ID mapping for phrases you use often","In LLM tool descriptions, enumerate the accepted aliases so the model stops emitting prose"],"exampleFix":"# before\nget_macro_data(\"bank of japan rate\", \"2025-06-10\")\n# -> ValueError: 'bank of japan rate' is not a known macro alias or a valid FRED series ID. ...\n\n# after\nget_macro_data(\"interest_rate\", \"2025-06-10\")     # alias in MACRO_SERIES\nget_macro_data(\"IRSTCB01JPM156N\", \"2025-06-10\")    # raw FRED series ID (no spaces)","handlingStrategy":"validation","validationCode":"import re\nfrom tradingagents.dataflows.fred import MACRO_SERIES\n\ndef valid_fred_indicator(name: str) -> bool:\n    if not isinstance(name, str):\n        return False\n    key = name.strip().lower().replace(\" \", \"_\").replace(\"-\", \"_\")\n    if key in MACRO_SERIES:\n        return True\n    c = name.strip().upper()\n    return bool(c) and len(c) <= 30 and not any(ch.isspace() for ch in c)","typeGuard":"def is_fred_series_id(s: str) -> bool:\n    return bool(re.fullmatch(r\"[A-Z0-9]{1,30}\", s or \"\"))","tryCatchPattern":"try:\n    get_macro_data(indicator, curr_date)\nexcept ValueError as e:\n    if \"not a known macro alias\" in str(e):\n        indicator = \"cpi\"  # or re-prompt the LLM with aliases + example IDs\n    else:\n        raise","preventionTips":["Give the LLM the alias list and 2-3 example series IDs in the tool schema","Add a normalization map for recurring natural-language queries instead of passing them through","Search FRED's series API first when unsure of the ID"],"tags":["validation","fred","macro-data","llm-input","valueerror"],"backgroundTag":null,"analyzedSha":"a33fd4c0f134485a43553a2c23a63cb14adbd88f","analyzedAt":"2026-08-14T19:45:16.920Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}