def tag_samples(self, tags):
        """Adds the tag(s) to all samples in this collection, if necessary.

        Args:
            tags: a tag or iterable of tags
        """
        if etau.is_str(tags):
            update = {"$addToSet": {"tags": tags}}
        else:
            update = {"$addToSet": {"tags": {"$each": list(tags)}}}

        # We only need to process samples that are missing a tag of interest
        view = self.match_tags(tags, bool=False, all=True)

        try:
            view._edit_sample_tags(update)
        except ValueError as e:
            #
            # $addToSet cannot handle null-valued fields, so if we get an error
            # about null-valued fields, replace them with [] and try again.
            # Note that its okay to run $addToSet multiple times as the tag
            # won't be added multiple times.
            #
            # For future reference, the error message looks roughly like this:
            #   ValueError: Cannot apply $addToSet to non-array field. Field
            #               named 'tags' has non-array type null
            #
            if "null" in str(e):
                none_tags = self.exists("tags", bool=False)
                none_tags.set_field("tags", []).save()

                view._edit_sample_tags(update)
            else:
                raise e
Adds the tag(s) to all samples in this collection, if necessary.

        Args:
            tags: a tag or iterable of tags
        
fiftyone/core/collections.py