{"record":{"id":"93043adec8a966d2","repo":"OpenBB-finance/OpenBB","slug":"requested-start-date-start-date-is-after-the-l","errorCode":null,"errorMessage":"Requested start_date '{start_date}' is after the latest available data '{time_end}'. Available date range: {time_start} to {time_end}","messagePattern":"Requested start_date '(.+?)' is after the latest available data '(.+?)'\\. Available date range: (.+?) to (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"openbb_platform/providers/imf/openbb_imf/utils/query_builder.py","lineNumber":289,"sourceCode":"\n                    # Fall back to dataConstraints if not found\n                    if not (time_start and time_end):\n                        data_constraints = data.get(\"dataConstraints\", [])\n                        for constraint in data_constraints:\n                            for annotation in constraint.get(\"annotations\", []):\n                                ann_id = annotation.get(\"id\", \"\")\n                                ann_title = annotation.get(\"title\", \"\")\n                                if ann_id == \"time_period_start\":\n                                    time_start = ann_title\n                                elif ann_id == \"time_period_end\":\n                                    time_end = ann_title\n\n                    if time_start and time_end:\n                        # Use >= because time_end represents the END of the last period\n                        # e.g., time_end=2025-01-01 means data up to end of 2024\n                        # So start_date=2025-01-01 would be requesting data AFTER the available range\n                        if start_date and start_date >= time_end:\n                            raise ValueError(\n                                f\"Requested start_date '{start_date}' is after the latest available data '{time_end}'. \"\n                                f\"Available date range: {time_start} to {time_end}\"\n                            )\n                        if end_date and end_date <= time_start:\n                            raise ValueError(\n                                f\"Requested end_date '{end_date}' is before the earliest available data '{time_start}'. \"\n                                f\"Available date range: {time_start} to {time_end}\"\n                            )\n\n        except KeyError as e:\n            # Dataflow not found or other metadata issue - let it pass through\n            warnings.warn(\n                f\"Could not validate constraints for dataflow '{dataflow}': {e}\",\n                OpenBBWarning,\n            )\n\n    def fetch_data(\n        self,","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/imf/openbb_imf/utils/query_builder.py#L271-L307","documentation":"build_url validates requested dates against the dataflow's TIME_PERIOD content constraints (annotations time_period_start/time_period_end). If start_date >= time_end (end is exclusive-ish: it marks the end of the last period), the request is entirely outside available data and ValueError is raised with the true range.","triggerScenarios":"Asking for start_date='2025-01-01' when the dataflow's latest available period ends 2025-01-01 (i.e. data through 2024), or any start beyond the published time_end.","commonSituations":"Assuming data is more current than IMF has published; hardcoded 'current year' scripts in January before annual data lands; lagging quarterly releases.","solutions":["Set start_date to (or before) the time_end shown in the message, or omit start_date.","For 'latest data' semantics, request a generous historical window and take the last rows of the result.","Check the dataflow's coverage on the IMF data catalog page before hardcoding dates."],"exampleFix":"# before\nurl = qb.build_url('DATAFLOW', start_date='2025-01-01')  # range ends 2025-01-01\n\n# after\nurl = qb.build_url('DATAFLOW', start_date='2000-01-01')  # covers all available history","handlingStrategy":"validation","validationCode":"def clamp_start_date(qb, dataflow: str, start_date: str) -> str:\n    rng = get_time_period_range(qb, dataflow)  # from time_period_* annotations\n    if rng and start_date >= rng[1]:\n        return rng[0]\n    return start_date","typeGuard":null,"tryCatchPattern":"try:\n    url = qb.build_url(dataflow, start_date=start_date)\nexcept ValueError as e:\n    m = re.search(r'range: (.+) to (.+)', str(e))\n    if m and 'after the latest' in str(e):\n        url = qb.build_url(dataflow, start_date=m.group(1))\n    else:\n        raise","preventionTips":["For 'latest' data, request a wide window and slice client-side instead of start_date=today.","Read the dataflow's published time coverage before hardcoding dates.","Remember time_end marks the end of the last period; equality already fails the check."],"tags":["validation","imf","dates","date-range","sdmx"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}