Handle parsing errors#

iCalendar files from a source might contain invalid property values. By default, event components use error-tolerant parsing, allowing you to work with partially valid calendar data.

Note

To avoid repetition, the code examples in this chapter use the following imports.

>>> from icalendar import Calendar
>>> from icalendar.prop import vBrokenProperty

Check for parsing errors#

When a component is parsed, any properties with invalid values are recorded in the errors attribute. This attribute is a list of tuples containing the property name and error information.

>>> ical_str = b"""BEGIN:VCALENDAR
... VERSION:2.0
... PRODID:test
... BEGIN:VEVENT
... UID:test-123
... DTSTART:INVALID-DATE
... SUMMARY:Meeting
... END:VEVENT
... END:VCALENDAR"""
>>> cal = Calendar.from_ical(ical_str)
>>> event = cal.walk("VEVENT")[0]
>>> event.errors
[('DTSTART', "Expected datetime, date, or time. Got: 'INVALID-DATE'")]

Errors are populated immediately after parsing, without needing to access the problematic properties.

Access broken properties#

Properties that fail to parse are converted to vBrokenProperty instances. This preserves the raw value for inspection or round-trip serialization.

>>> dtstart = event["DTSTART"]
>>> isinstance(dtstart, vBrokenProperty)
True
>>> str(dtstart)
'INVALID-DATE'

The broken property includes metadata about the parsing failure.

>>> dtstart.property_name
'DTSTART'
>>> dtstart.expected_type
'vDDDTypes'
>>> dtstart.parse_error
"Expected datetime, date, or time. Got: 'INVALID-DATE'"

Work with partially valid data#

One broken property does not prevent access to other valid properties in the same component.

>>> ical_str = b"""BEGIN:VCALENDAR
... VERSION:2.0
... PRODID:test
... BEGIN:VEVENT
... UID:test-123
... DTSTART:INVALID-DATE
... DTEND:20250102T120000Z
... SUMMARY:Meeting
... END:VEVENT
... END:VCALENDAR"""
>>> cal = Calendar.from_ical(ical_str)
>>> event = cal.walk("VEVENT")[0]
>>> event["DTEND"].dt.year
2025
>>> str(event["SUMMARY"])
'Meeting'

Round-trip serialization#

Broken properties preserve their raw values, so they serialize correctly with to_ical().

>>> output = cal.to_ical()
>>> b"DTSTART:INVALID-DATE" in output
True

Handle errors programmatically#

You can iterate over errors to log or handle them.

>>> for prop_name, error_msg in event.errors:
...     print(f"{prop_name}: {error_msg}")
DTSTART: Expected datetime, date, or time. Got: 'INVALID-DATE'

To check if a specific property failed to parse, check if it is a vBrokenProperty.

>>> if isinstance(event["DTSTART"], vBrokenProperty):
...     print("DTSTART failed to parse")
DTSTART failed to parse