{"record":{"id":"0c4cf72e5d3c4de0","repo":"dgtlmoon/changedetection.io","slug":"invalid-time-str-time-str-must-be-in-hh-mm","errorCode":null,"errorMessage":"Invalid time_str: '{time_str}'. Must be in 'HH:MM' format.","messagePattern":"Invalid time_str: '(.+?)'\\. Must be in 'HH:MM' format\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"changedetectionio/time_handler.py","lineNumber":47,"sourceCode":"        timezone_str (str): The timezone identifier (e.g., 'Europe/Berlin').\n        duration (int, optional): The duration of the time range in minutes. Default is 15.\n\n    Returns:\n        bool: True if the current time is within the time range, False otherwise.\n    \"\"\"\n    # Parse the target day of the week\n    try:\n        target_weekday = Weekday[day_of_week.capitalize()]\n    except KeyError:\n        raise ValueError(f\"Invalid day_of_week: '{day_of_week}'. Must be a valid weekday name.\")\n\n    # Parse the start time\n    try:\n        hour, minute = map(int, time_str.split(':'))\n        if not (0 <= hour <= 23 and 0 <= minute <= 59):\n            raise ValueError\n    except (ValueError, AttributeError):\n        raise ValueError(f\"Invalid time_str: '{time_str}'. Must be in 'HH:MM' format.\")\n\n    # Get the current time in the specified timezone\n    try:\n        now_tz = arrow.now(timezone_str.strip())\n    except Exception as e:\n        raise ValueError(f\"Invalid timezone_str: '{timezone_str}'. Must be a valid timezone identifier.\")\n\n    # Check if the current day matches the target day or overlaps due to duration\n    current_weekday = now_tz.weekday()\n    # Create start datetime for today in target timezone\n    start_datetime_tz = now_tz.replace(hour=hour, minute=minute, second=0, microsecond=0)\n\n    # Handle previous day's overlap\n    if target_weekday == (current_weekday - 1) % 7:\n        # Calculate start and end times for the overlap from the previous day\n        start_datetime_tz = start_datetime_tz.shift(days=-1)\n        end_datetime_tz = start_datetime_tz.shift(minutes=duration)\n        if start_datetime_tz <= now_tz <= end_datetime_tz:","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/dgtlmoon/changedetection.io/blob/5d9c7c6da76340597243e8163c4f2439237fa0e8/changedetectionio/time_handler.py#L29-L65","documentation":"ValueError raised by am_i_inside_time when time_str cannot be parsed as HH:MM: the split(':') + int() conversion fails, or the parsed hour/minute are out of range (hour 0-23, minute 0-59). AttributeError is also caught, so a non-string time_str (None, int) triggers the same message.","triggerScenarios":"Calling am_i_inside_time with time_str like '9:0:0', '0900', '25:00', '12:5pm', None, or 900 (int). Any deviation from exactly two colon-separated integers in valid range raises.","commonSituations":"Schedule forms filled with 24h+ formats or AM/PM text; scripts building 'HH:MM' with f-strings that omit zero-padding ('9:5' is actually fine — int() handles it — but '9' alone fails); users copying times from locales using '.' or ',' separators ('09.30').","solutions":["Format times as zero-padded 24-hour 'HH:MM' (e.g. '09:30', '23:59')","Validate with a regex like ^([01]?\\d|2[0-3]):[0-5]\\d$ before storing/submitting","Convert AM/PM input to 24h format in your integration layer","Reject schedule settings early in your UI/API with a clear message instead of letting am_i_inside_time throw"],"exampleFix":"# before\nam_i_inside_time('monday', '9:30 AM', '1', 'utc')\n# after\nam_i_inside_time('monday', '09:30', '1', 'utc')","handlingStrategy":"validation","validationCode":"import re\nif not re.fullmatch(r'([01]?\\d|2[0-3]):[0-5]\\d', time_str or ''):\n    raise ValueError('time must be HH:MM 24h')","typeGuard":"import re\ndef is_valid_hhmm(s: str) -> bool:\n    return bool(re.fullmatch(r'([01]?\\d|2[0-3]):[0-5]\\d', s or ''))","tryCatchPattern":"try:\n    inside = am_i_inside_time(day, time_str, duration, tz)\nexcept ValueError as e:\n    return bad_request(str(e))  # distinguishes day/time/timezone in message","preventionTips":["Always submit zero-padded 24h times; convert AM/PM client-side","Validate schedule JSON before writing it to a watch","Use HTML input type=\"time\" in UIs to guarantee HH:MM format"],"tags":["schedule","time-format","time-handler","value-error"],"backgroundTag":"invalid-schedule-config","analyzedSha":"5d9c7c6da76340597243e8163c4f2439237fa0e8","analyzedAt":"2026-08-27T19:41:16.067Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}