# Buggy code
def ProduceEventWithEventData(self, event, event_data):
    """Produces an event.

    Args:
      event (EventObject): event.
      event_data (EventData): event data.

    Raises:
      InvalidEvent: if the event timestamp value is not set or out of bounds.
    """
    if event.timestamp is None:
        raise errors.InvalidEvent("Event timestamp value not set.")

    if event.timestamp < self._INT64_MIN or event.timestamp > self._INT64_MAX:
        raise errors.InvalidEvent("Event timestamp value out of bounds.")

    event_data_hash = event_data.GetAttributeValuesHash()
    if event_data_hash != self._last_event_data_hash:
        # Make a copy of the event data before adding additional values.
        event_data = copy.deepcopy(event_data)

        self.ProcessEventData(
            event_data, parser_chain=self.GetParserChain(), file_entry=self._file_entry
        )

        self._storage_writer.AddEventData(event_data)

        self._last_event_data_hash = event_data_hash
        self._last_event_data_identifier = event_data.GetIdentifier()

    if self._last_event_data_identifier:
        event.SetEventDataIdentifier(self._last_event_data_identifier)

    # TODO: remove this after structural fix is in place
    # https://github.com/log2timeline/plaso/issues/1691
    event.parser = self.GetParserChain()

    self._storage_writer.AddEvent(event)
    self._number_of_events += 1

    self.last_activity_timestamp = time.time()


# Traceback (ValueError)
Traceback (most recent call last):
File "plaso/tools/log2timeline.py", line 97, in <module>
if not Main():
File "plaso/tools/log2timeline.py", line 72, in Main
tool.ExtractEventsFromSources()
File "plaso/plaso/cli/log2timeline_tool.py", line 448, in ExtractEventsFromSources
worker_memory_limit=self._worker_memory_limit)
File "plaso/plaso/multi_processing/task_engine.py", line 812, in ProcessSources
self._ProcessSources(source_path_specs, storage_writer)
File "plaso/plaso/multi_processing/task_engine.py", line 343, in _ProcessSources
self._ScheduleTasks(storage_writer)
File "plaso/plaso/multi_processing/task_engine.py", line 449, in _ScheduleTasks
self._MergeTaskStorage(storage_writer)
File "plaso/plaso/multi_processing/task_engine.py", line 256, in _MergeTaskStorage
maximum_number_of_containers=self._MAXIMUM_NUMBER_OF_CONTAINERS)
File "plaso/plaso/storage/sqlite/merge_reader.py", line 278, in MergeAttributeContainers
self._active_container_type, serialized_data)
File "plaso/plaso/storage/interface.py", line 600, in _DeserializeAttributeContainer
attribute_container = self._serializer.ReadSerialized(serialized_string)
File "plaso/plaso/serializer/json_serializer.py", line 404, in ReadSerialized
return cls.ReadSerializedDict(json_dict)
File "plaso/plaso/serializer/json_serializer.py", line 423, in ReadSerializedDict
json_object = cls._ConvertDictToObject(json_dict)
File "plaso/plaso/serializer/json_serializer.py", line 252, in _ConvertDictToObject
'supported.').format(attribute_name))
ValueError: Event data attribute value: return_value of type dict is not supported.

# Fixed code
def ProduceEventWithEventData(self, event, event_data):
    """Produces an event.

    Args:
      event (EventObject): event.
      event_data (EventData): event data.

    Raises:
      InvalidEvent: if the event timestamp value is not set or out of bounds or
          if the event data (attribute container) values cannot be hashed.
    """
    if event.timestamp is None:
        raise errors.InvalidEvent("Event timestamp value not set.")

    if event.timestamp < self._INT64_MIN or event.timestamp > self._INT64_MAX:
        raise errors.InvalidEvent("Event timestamp value out of bounds.")

    try:
        event_data_hash = event_data.GetAttributeValuesHash()
    except TypeError as exception:
        raise errors.InvalidEvent(
            "Unable to hash event data values with error: {0!s}".format(exception)
        )

    if event_data_hash != self._last_event_data_hash:
        # Make a copy of the event data before adding additional values.
        event_data = copy.deepcopy(event_data)

        self.ProcessEventData(
            event_data, parser_chain=self.GetParserChain(), file_entry=self._file_entry
        )

        self._storage_writer.AddEventData(event_data)

        self._last_event_data_hash = event_data_hash
        self._last_event_data_identifier = event_data.GetIdentifier()

    if self._last_event_data_identifier:
        event.SetEventDataIdentifier(self._last_event_data_identifier)

    # TODO: remove this after structural fix is in place
    # https://github.com/log2timeline/plaso/issues/1691
    event.parser = self.GetParserChain()

    self._storage_writer.AddEvent(event)
    self._number_of_events += 1

    self.last_activity_timestamp = time.time()