python/cpython · error · ValueError

ISO week directive '%V' must be used with the ISO year direc

Error message

ISO week directive '%V' must be used with the ISO year directive '%G' and a weekday directive ('%A', '%a', '%w', or '%u').

What it means

Mirror of the %G case: %V matched (iso_week is not None) but the regular year is missing or no weekday directive matched, so the week number cannot be anchored to a year. _strptime refuses rather than defaulting the year (defaulting ISO values is explicitly avoided per the comment 'don't assume default values for ISO week/year').

Source

Thrown at Lib/_strptime.py:746

                        break
                    else:
                        tz = value
                        break

    # Deal with the cases where ambiguities arise
    # don't assume default values for ISO week/year
    if iso_year is not None:
        if julian is not None:
            raise ValueError("Day of the year directive '%j' is not "
                             "compatible with ISO year directive '%G'. "
                             "Use '%Y' instead.")
        elif iso_week is None or weekday is None:
            raise ValueError("ISO year directive '%G' must be used with "
                             "the ISO week directive '%V' and a weekday "
                             "directive ('%A', '%a', '%w', or '%u').")
    elif iso_week is not None:
        if year is None or weekday is None:
            raise ValueError("ISO week directive '%V' must be used with "
                             "the ISO year directive '%G' and a weekday "
                             "directive ('%A', '%a', '%w', or '%u').")
        else:
            raise ValueError("ISO week directive '%V' is incompatible with "
                             "the year directive '%Y'. Use the ISO year '%G' "
                             "instead.")

    leap_year_fix = False
    if year is None:
        if month == 2 and day == 29:
            year = 1904  # 1904 is first leap year of 20th century
            leap_year_fix = True
        else:
            year = 1900

    # If we know the week of the year and what day of that week, we can figure
    # out the Julian day of the year.
    if julian is None and weekday is not None:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Add %G (and a weekday if missing) to the format: '2020 W12 3' with '%G W%V %u'
  2. If %V must pair with a plain year, that is error 272's case — it is not allowed; convert the year to an ISO year first (date.isocalendar())

Example fix

# before
>>> datetime.strptime('W12 3', 'W%V %u')
ValueError: ISO week directive '%V' must be used with the ISO year directive '%G' and a weekday directive ('%A', '%a', '%w', or '%u').

# after
>>> datetime.strptime('2020 W12 3', '%G W%V %u')
datetime.datetime(2020, 3, 18, 0, 0)
Defensive patterns

Strategy: validation

Validate before calling

def need_iso_year(fmt: str) -> bool:
    clean = fmt.replace('%%', '')
    return '%V' in clean and '%G' not in clean

Prevention

When it happens

Trigger: datetime.strptime('W12 3', 'W%V %u') — %V with a weekday but no year; or datetime.strptime('W12', 'W%V') with neither year nor weekday.

Common situations: Parsing week numbers without year context (retail/financial week reports); log formats that emit only week and weekday.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/4a9cb8517a1c2cde. Report an issue: GitHub.