{"record":{"id":"5a5b9018e14f1fa5","repo":"OpenBB-finance/OpenBB","slug":"frequency-must-be-one-of-a-q-or-m","errorCode":null,"errorMessage":"Frequency must be one of 'A', 'Q', or 'M'.","messagePattern":"Frequency must be one of 'A', 'Q', or 'M'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/imf/openbb_imf/utils/dot_helpers.py","lineNumber":170,"sourceCode":"    **kwargs : dict\n        Additional query parameters to pass to the API.\n\n    Returns\n    -------\n    dict\n        A dictionary with keys: 'data' containing the fetched data,\n        and 'metadata' containing the related metadata.\n    \"\"\"\n    # pylint: disable=import-outside-toplevel\n    from openbb_imf.utils.query_builder import ImfQueryBuilder\n\n    if not country or not counterpart:\n        raise ValueError(\"Country and counterpart parameters cannot be empty.\")\n\n    freq = freq[0].upper()\n\n    if freq and freq not in [\"A\", \"Q\", \"M\"]:\n        raise ValueError(\"Frequency must be one of 'A', 'Q', or 'M'.\")\n\n    query_builder = ImfQueryBuilder()\n    dataflow_id = \"IMTS\"\n    params = query_builder.metadata.get_dataflow_parameters(dataflow_id)\n    country_values = {item[\"value\"] for item in params.get(\"COUNTRY\", [])}\n    counterpart_values = {\n        item[\"value\"]\n        for item in params.get(\"COUNTERPART_COUNTRY\", params.get(\"COUNTRY\", []))\n    }\n\n    def _validate_selection(selection, valid_values, name):\n        \"\"\"Validate country or counterpart selection.\"\"\"\n        if not valid_values:\n            return selection\n\n        # Handle wildcards - return \"*\" as-is\n        if selection == \"*\":\n            return \"*\"","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/imf/openbb_imf/utils/dot_helpers.py#L152-L188","documentation":"imts_query only accepts annual ('A'), quarterly ('Q'), or monthly ('M') frequencies because those are the only periods the IMTS dataflow publishes. The code takes freq[0].upper() — so the first character decides — and rejects anything whose first letter is not A/Q/M. Full words like 'annual' work ('a'->'A'), but 'weekly', 'daily', 'W', 'D' fail.","triggerScenarios":"freq='W', freq='daily' ('d'), freq='weekly' ('w'), or a freq string copied from another provider's vocabulary (e.g. 'B' for business from FRED-style APIs).","commonSituations":"Reusing a frequency parameter across multiple providers in one script; new users guessing 'Y' for yearly instead of 'A'; passing pandas offset aliases ('QS', 'ME').","solutions":["Use 'A' (annual), 'Q' (quarterly), or 'M' (monthly) — or words starting with those letters ('annual', 'quarterly', 'monthly').","Map your internal frequency enum to IMFS vocabulary before calling: {'yearly':'A','quarterly':'Q','monthly':'M'}.","Remember only the first character is inspected, so avoid multi-char codes entirely."],"exampleFix":"# before\nres = imts_query(country='USA', counterpart='DEU', indicator='TXG_FOB_USD', freq='W')\n\n# after\nres = imts_query(country='USA', counterpart='DEU', indicator='TXG_FOB_USD', freq='M')","handlingStrategy":"validation","validationCode":"FREQ_MAP = {'A': 'A', 'Q': 'Q', 'M': 'M',\n            'Y': 'A', 'ANNUAL': 'A', 'YEARLY': 'A',\n            'QUARTERLY': 'Q', 'MONTHLY': 'M'}\nfreq = FREQ_MAP.get(freq.strip().upper())\nif freq is None:\n    raise ValueError(f\"Unsupported frequency; use one of A/Q/M (got {freq!r}).\")","typeGuard":"def is_imts_freq(freq: str | None) -> bool:\n    return freq is None or (isinstance(freq, str) and freq[:1].upper() in {'A', 'Q', 'M'})","tryCatchPattern":"try:\n    res = imts_query(country=c, counterpart=cp, indicator=ind, freq=freq)\nexcept ValueError as e:\n    if 'Frequency must be' in str(e):\n        res = imts_query(country=c, counterpart=cp, indicator=ind, freq='A')\n    else:\n        raise","preventionTips":["Map your app's frequency enum to A/Q/M at the boundary.","Note only freq[0] is inspected — 'annual' passes, 'yearly' fails.","Never forward FRED-style codes ('Q', ok) vs ('W', 'D' fail) blindly."],"tags":["validation","imf","frequency","dot","parameters"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}