{"record":{"id":"06a36309b8c68fdb","repo":"pandas-dev/pandas","slug":"of-the-four-parameters-start-end-periods-and-f","errorCode":null,"errorMessage":"Of the four parameters: start, end, periods, and freq, exactly three must be specified","messagePattern":"Of the four parameters: start, end, periods, and freq, exactly three must be specified","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimes.py","lineNumber":409,"sourceCode":"        cls,\n        start,\n        end,\n        periods: int | None,\n        freq,\n        tz=None,\n        normalize: bool = False,\n        ambiguous: TimeAmbiguous = \"raise\",\n        nonexistent: TimeNonexistent = \"raise\",\n        inclusive: IntervalClosedType = \"both\",\n        *,\n        unit: TimeUnit = \"ns\",\n    ) -> Self:\n        periods = dtl.validate_periods(periods)\n        if freq is None and any(x is None for x in [periods, start, end]):\n            raise ValueError(\"Must provide freq argument if no data is supplied\")\n\n        if com.count_not_none(start, end, periods, freq) != 3:\n            raise ValueError(\n                \"Of the four parameters: start, end, periods, \"\n                \"and freq, exactly three must be specified\"\n            )\n        freq = to_offset(freq)\n\n        if start is not None:\n            start = Timestamp(start)\n\n        if end is not None:\n            end = Timestamp(end)\n\n        if start is NaT or end is NaT:\n            raise ValueError(\"Neither `start` nor `end` can be NaT\")\n\n        if unit is not None:\n            if unit not in [\"s\", \"ms\", \"us\", \"ns\"]:\n                raise ValueError(\"'unit' must be one of 's', 'ms', 'us', 'ns'\")\n        else:","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/datetimes.py#L391-L427","documentation":"Raised by DatetimeArray._generate_range when com.count_not_none(start, end, periods, freq) != 3. The generator requires exactly three of the four parameters so the fourth is unambiguously inferred; providing two, all four, or only one is rejected. Note this fires after the 'freq missing' guard, so freq is already non-None when reached.","triggerScenarios":"pd.date_range(start, end) with neither periods nor freq (only two of four); pd.date_range(start, end, periods, freq) supplying all four; pd.date_range(start, freq) with two None.","commonSituations":"Over-specifying after a refactor (adding periods while keeping freq); under-specifying when freq defaults to None; conditional logic that sometimes leaves two args set.","solutions":["Provide exactly three: start+end+freq, start+end+periods, start+periods+freq, or end+periods+freq.","If you have start and end only, omit one of periods/freq intentionally and pass the other.","Use com.count_not_none(start,end,periods,freq)==3 as an upstream assert."],"exampleFix":"// before\npd.date_range('2020-01-01', '2020-01-10')  # ValueError: exactly three must be specified\n\n// after\npd.date_range('2020-01-01', '2020-01-10', freq='D')  # periods inferred","handlingStrategy":"validation","validationCode":"def safe_date_range(start=None, end=None, periods=None, freq=None):\n    n = sum(x is not None for x in [start, end, periods, freq])\n    if n != 3:\n        raise ValueError(f\"Need exactly 3 of start/end/periods/freq, got {n}\")\n    return pd.date_range(start=start, end=end, periods=periods, freq=freq)","typeGuard":"def exactly_three_of_four(start, end, periods, freq) -> bool:\n    return sum(x is not None for x in [start, end, periods, freq]) == 3","tryCatchPattern":"try:\n    rng = pd.date_range(start=start, end=end, periods=periods, freq=freq)\nexcept ValueError as e:\n    if \"exactly three must be specified\" in str(e):\n        # drop one arg or supply the missing one intentionally\n        rng = pd.date_range(start=start, end=end, freq=\"D\")\n    else:\n        raise","preventionTips":["Use pd.core.common.count_not_none(...) in an upstream assert.","Keep date_range call sites explicit about which three args are set.","Avoid defaulting multiple of these args to None simultaneously."],"tags":["pandas","date-range","validation","parameters"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}