Skip to content

Errors

Error handling and exception classes for HED validation and processing.

Exception Classes

HedFileError

HedFileError

Bases: Exception

Exception raised when a file cannot be parsed due to being malformed, file IO, etc.

Source code in hed/errors/exceptions.py
class HedFileError(Exception):
    """Exception raised when a file cannot be parsed due to being malformed, file IO, etc."""
    def __init__(self, code, message, filename, issues=None):
        self.code = code
        self.message = message
        self.filename = filename
        self.issues = issues
        if self.issues is None:
            self.issues = []

HedExceptions

HedExceptions

HED exception codes.

Source code in hed/errors/exceptions.py
class HedExceptions:
    """ HED exception codes. """
    GENERIC_ERROR = 'GENERIC_ERROR'
    # A list of all exceptions that can be generated by the hedtools.
    URL_ERROR = "URL_ERROR"
    FILE_NOT_FOUND = 'fileNotFound'
    BAD_PARAMETERS = 'badParameters'
    CANNOT_PARSE_XML = 'cannotParseXML'
    CANNOT_PARSE_JSON = 'cannotParseJson'
    INVALID_EXTENSION = 'invalidExtension'
    INVALID_HED_FORMAT = 'INVALID_HED_FORMAT'

    INVALID_DATAFRAME = 'INVALID_DATAFRAME'
    INVALID_FILE_FORMAT = 'INVALID_FILE_FORMAT'

    # These are actual schema issues, not that the file cannot be found or parsed
    SCHEMA_HEADER_MISSING = 'SCHEMA_HEADER_INVALID'
    SCHEMA_HEADER_INVALID = 'SCHEMA_HEADER_INVALID'
    SCHEMA_UNKNOWN_HEADER_ATTRIBUTE = "SCHEMA_HEADER_INVALID"

    SCHEMA_LIBRARY_INVALID = "SCHEMA_LIBRARY_INVALID"
    BAD_HED_LIBRARY_NAME = 'SCHEMA_LIBRARY_INVALID'
    BAD_WITH_STANDARD = "SCHEMA_LIBRARY_INVALID"
    BAD_WITH_STANDARD_MULTIPLE_VALUES = "SCHEMA_LOAD_FAILED"
    ROOTED_TAG_INVALID = "SCHEMA_LIBRARY_INVALID"
    ROOTED_TAG_HAS_PARENT = "SCHEMA_LIBRARY_INVALID"
    ROOTED_TAG_DOES_NOT_EXIST = "SCHEMA_LIBRARY_INVALID"
    IN_LIBRARY_IN_UNMERGED = "SCHEMA_LIBRARY_INVALID"
    INVALID_LIBRARY_PREFIX = "SCHEMA_LIBRARY_INVALID"

    SCHEMA_VERSION_INVALID = 'SCHEMA_VERSION_INVALID'
    SCHEMA_SECTION_MISSING = 'SCHEMA_SECTION_MISSING'
    SCHEMA_INVALID = 'SCHEMA_INVALID'

    WIKI_SEPARATOR_INVALID = 'invalidSectionSeparator'

    # This issue will contain a list of lines with issues.
    WIKI_DELIMITERS_INVALID = 'WIKI_DELIMITERS_INVALID'
    WIKI_LINE_START_INVALID = 'WIKI_LINE_START_INVALID'
    WIKI_LINE_INVALID = 'WIKI_LINE_INVALID'
    HED_SCHEMA_NODE_NAME_INVALID = 'HED_SCHEMA_NODE_NAME_INVALID'

    SCHEMA_DUPLICATE_PREFIX = 'SCHEMA_LOAD_FAILED'
    SCHEMA_DUPLICATE_LIBRARY = "SCHEMA_LIBRARY_INVALID"
    BAD_COLUMN_NAMES = 'BAD_COLUMN_NAMES'

    SCHEMA_DUPLICATE_NAMES = "SCHEMA_DUPLICATE_NAMES"

    CANNOT_PARSE_RDF = "CANNOT_PARSE_RDF"
    SCHEMA_LOAD_FAILED = "SCHEMA_LOAD_FAILED"

    SCHEMA_TAG_TSV_BAD_PARENT = "SCHEMA_TAG_TSV_BAD_PARENT"

Error Reporting

ErrorHandler

ErrorHandler

Class to hold error context and having general error functions.

Source code in hed/errors/error_reporter.py
class ErrorHandler:
    """Class to hold error context and having general error functions."""
    def __init__(self, check_for_warnings=True):
        # The current (ordered) dictionary of contexts.
        self.error_context = []
        self._check_for_warnings = check_for_warnings

    def push_error_context(self, context_type, context):
        """ Push a new error context to narrow down error scope.

        Parameters:
            context_type (str): A value from ErrorContext representing the type of scope.
            context (str, int, or HedString): The main value for the context_type.

        Notes:
            The context depends on the context_type. For ErrorContext.FILE_NAME this would be the actual filename.

        """
        if context is None:
            if context_type in int_sort_list:
                context = 0
            else:
                context = ""
        self.error_context.append((context_type, context))

    def pop_error_context(self):
        """ Remove the last scope from the error context.

        Notes:
            Modifies the error context of this reporter.

        """

        self.error_context.pop(-1)

    def reset_error_context(self):
        """ Reset all error context information to defaults.

        Notes:
            This function is mainly for testing and should not be needed with proper usage.

        """
        self.error_context = []

    def add_context_and_filter(self, issues):
        """ Filter out warnings if requested, while adding context to issues.

            issues(list):
                list:   A list containing a single dictionary representing a single error.
        """
        if not self._check_for_warnings:
            issues[:] = self.filter_issues_by_severity(issues, ErrorSeverity.ERROR)

        for error_object in issues:
            self._add_context_to_error(error_object, self.error_context)
            self._update_error_with_char_pos(error_object)

    def format_error_with_context(self, *args, **kwargs):
        error_object = ErrorHandler.format_error(*args, **kwargs)
        if self is not None:
            actual_error = error_object[0]
            # # Filter out warning errors
            if not self._check_for_warnings and actual_error['severity'] >= ErrorSeverity.WARNING:
                return []
            self._add_context_to_error(actual_error, self.error_context)
            self._update_error_with_char_pos(actual_error)

        return error_object

    @staticmethod
    def filter_issues_by_severity(issues_list: list[dict], severity: int) -> list[dict]:
        """ Gather all issues matching or below a given severity.

        Parameters:
            issues_list (list[dict]): A list of dictionaries containing the full issue list.
            severity (int): The level of issues to keep.

        Returns:
            list[dict]: A list of dictionaries containing the issue list after filtering by severity.

        """
        return [issue for issue in issues_list if issue['severity'] <= severity]

    @staticmethod
    def format_error(error_type: str, *args, actual_error=None, **kwargs) -> list[dict]:
        """ Format an error based on the parameters, which vary based on what type of error this is.

        Parameters:
            error_type (str): The type of error for this. Registered with @hed_error or @hed_tag_error.
            args (args): Any remaining non-keyword args after those required by the error type.
            actual_error (str or None): Code to actually add to report out.
            kwargs (kwargs): The other keyword args to pass down to the error handling func.

        Returns:
            list[dict]: A list containing a single dictionary representing a single error.

        Notes:
            The actual error is useful for errors that are shared like invalid character.

        """
        error_func = error_functions.get(error_type)
        if not error_func:
            error_object = ErrorHandler.val_error_unknown(*args, **kwargs)
            error_object['code'] = error_type
        else:
            error_object = error_func(*args, **kwargs)

        if actual_error:
            error_object['code'] = actual_error

        return [error_object]

    @staticmethod
    def format_error_from_context(error_type: str, error_context: list, *args, actual_error: Optional[str], **kwargs) -> list[dict]:
        """ Format an error based on the error type.

        Parameters:
            error_type (str): The type of error. Registered with @hed_error or @hed_tag_error.
            error_context (list): Contains the error context to use for this error.
            args (args): Any remaining non-keyword args.
            actual_error (str or None): Error code to actually add to report out.
            kwargs (kwargs): Keyword parameters to pass down to the error handling func.

        Returns:
            list[dict]: A list containing a single dictionary.

        Notes:
            - Generally the error_context is returned from _add_context_to_error.
            - The actual_error is useful for errors that are shared like invalid character.
            - This can't filter out warnings like the other ones.

        """
        error_list = ErrorHandler.format_error(error_type, *args, actual_error=actual_error, **kwargs)

        ErrorHandler._add_context_to_error(error_list[0], error_context)
        ErrorHandler._update_error_with_char_pos(error_list[0])
        return error_list

    @staticmethod
    def _add_context_to_error(error_object: dict, error_context_to_add: list) -> list[dict]:
        """ Add relevant context such as row number or column name around an error object.

        Parameters:
            error_object (dict): Generated error containing at least a code and message entry.
            error_context_to_add (list): Source context to use. If none, the error handler context is used.

        Returns:
            dict: A list of dict with needed context strings added at the beginning of the list.

        """
        for (context_type, context) in error_context_to_add:
            error_object[context_type] = context

        return error_object

    @staticmethod
    def _create_error_object(error_type, base_message, severity, **kwargs):
        error_object = {'code': error_type,
                        'message': base_message,
                        'severity': severity
                        }

        for key, value in kwargs.items():
            error_object.setdefault(key, value)

        return error_object

    @staticmethod
    def _get_tag_span_to_error_object(error_object):
        if ErrorContext.HED_STRING not in error_object:
            return None, None

        if 'source_tag' in error_object:
            source_tag = error_object['source_tag']
            if isinstance(source_tag, int):
                return None, None
        else:
            return None, None

        hed_string = error_object[ErrorContext.HED_STRING]
        span = hed_string._get_org_span(source_tag)
        return span

    @staticmethod
    def _update_error_with_char_pos(error_object):
        # This part is optional as you can always generate these as needed.
        start, end = ErrorHandler._get_tag_span_to_error_object(error_object)
        if start is not None:
            # silence warning in pycharm
            start = int(start)
            source_tag = error_object.get('source_tag', None)
            # Todo: Move this functionality somewhere more centralized.
            # If the tag has been modified from the original, don't try to use sub indexing.
            if source_tag and source_tag._tag:
                new_start, new_end = start, end
            else:
                new_start = start + error_object.get('index_in_tag', 0)
                index_in_tag_end = end
                if 'index_in_tag_end' in error_object:
                    index_in_tag_end = start + error_object['index_in_tag_end']
                new_end = index_in_tag_end
            error_object['char_index'], error_object['char_index_end'] = new_start, new_end
            error_object['message'] += f"  Problem spans string indexes: {new_start}, {new_end}"

    @hed_error("Unknown")
    def val_error_unknown(*args, **kwargs) -> str:
        """ Default error handler if no error of this type was registered.

        Parameters:
            args (args): List of non-keyword parameters (varies).
            kwargs (kwargs): Keyword parameters (varies)

        Returns:
            str: The error message.

        """
        return f"Unknown error. Args: {str(args), str(kwargs)}"

    @staticmethod
    def filter_issues_by_count(issues, count, by_file=False)-> tuple[list[dict], dict[str, int]]:
        """ Filter the issues list to only include the first count issues of each code.

        Parameters:
            issues (list): A list of dictionaries containing the full issue list.
            count (int): The number of issues to keep for each code.
            by_file (bool): If True, group by file name.

    Returns:
        tuple[list[dict], dict[str, int]]: A tuple containing:
            - A list of dictionaries representing the filtered issue list.
            - A dictionary with the codes as keys and the number of occurrences as values.

        """
        total_seen = {}
        file_dicts = {'': {}}
        filtered_issues = []
        for issue in issues:
            seen_codes = file_dicts['']
            if by_file and 'ec_filename' in issue:
                file_name = issue['ec_filename']
                if file_name not in file_dicts:
                    file_dicts[file_name] = {}
                seen_codes = file_dicts[file_name]

            code = issue['code']
            if code not in seen_codes:
                seen_codes[code] = 0
            seen_codes[code] += 1
            if seen_codes[code] > count:
                continue
            filtered_issues.append(issue)

        return filtered_issues, ErrorHandler.aggregate_code_counts(file_dicts)

    @staticmethod
    def aggregate_code_counts(file_code_dict) -> dict:
        """ Aggregate the counts of codes across multiple files.

        Parameters:
            file_code_dict (dict): A dictionary where keys are filenames and values are dictionaries of code counts.

        Returns:
            dict: A dictionary with the aggregated counts of codes across all files.
        """
        total_counts = defaultdict(int)
        for file_dict in file_code_dict.values():
            for code, count in file_dict.items():
                total_counts[code] += count
        return dict(total_counts)

add_context_and_filter

add_context_and_filter(issues)

Filter out warnings if requested, while adding context to issues.

issues(list): list: A list containing a single dictionary representing a single error.

Source code in hed/errors/error_reporter.py
def add_context_and_filter(self, issues):
    """ Filter out warnings if requested, while adding context to issues.

        issues(list):
            list:   A list containing a single dictionary representing a single error.
    """
    if not self._check_for_warnings:
        issues[:] = self.filter_issues_by_severity(issues, ErrorSeverity.ERROR)

    for error_object in issues:
        self._add_context_to_error(error_object, self.error_context)
        self._update_error_with_char_pos(error_object)

aggregate_code_counts staticmethod

aggregate_code_counts(file_code_dict) -> dict

Aggregate the counts of codes across multiple files.

Parameters:

Name Type Description Default
file_code_dict dict

A dictionary where keys are filenames and values are dictionaries of code counts.

required

Returns:

Name Type Description
dict dict

A dictionary with the aggregated counts of codes across all files.

Source code in hed/errors/error_reporter.py
@staticmethod
def aggregate_code_counts(file_code_dict) -> dict:
    """ Aggregate the counts of codes across multiple files.

    Parameters:
        file_code_dict (dict): A dictionary where keys are filenames and values are dictionaries of code counts.

    Returns:
        dict: A dictionary with the aggregated counts of codes across all files.
    """
    total_counts = defaultdict(int)
    for file_dict in file_code_dict.values():
        for code, count in file_dict.items():
            total_counts[code] += count
    return dict(total_counts)

filter_issues_by_count staticmethod

filter_issues_by_count(
    issues, count, by_file=False
) -> tuple[list[dict], dict[str, int]]

Filter the issues list to only include the first count issues of each code.

Parameters:
    issues (list): A list of dictionaries containing the full issue list.
    count (int): The number of issues to keep for each code.
    by_file (bool): If True, group by file name.

Returns:

Type Description
tuple[list[dict], dict[str, int]]

tuple[list[dict], dict[str, int]]: A tuple containing: - A list of dictionaries representing the filtered issue list. - A dictionary with the codes as keys and the number of occurrences as values.

Source code in hed/errors/error_reporter.py
@staticmethod
def filter_issues_by_count(issues, count, by_file=False)-> tuple[list[dict], dict[str, int]]:
    """ Filter the issues list to only include the first count issues of each code.

    Parameters:
        issues (list): A list of dictionaries containing the full issue list.
        count (int): The number of issues to keep for each code.
        by_file (bool): If True, group by file name.

Returns:
    tuple[list[dict], dict[str, int]]: A tuple containing:
        - A list of dictionaries representing the filtered issue list.
        - A dictionary with the codes as keys and the number of occurrences as values.

    """
    total_seen = {}
    file_dicts = {'': {}}
    filtered_issues = []
    for issue in issues:
        seen_codes = file_dicts['']
        if by_file and 'ec_filename' in issue:
            file_name = issue['ec_filename']
            if file_name not in file_dicts:
                file_dicts[file_name] = {}
            seen_codes = file_dicts[file_name]

        code = issue['code']
        if code not in seen_codes:
            seen_codes[code] = 0
        seen_codes[code] += 1
        if seen_codes[code] > count:
            continue
        filtered_issues.append(issue)

    return filtered_issues, ErrorHandler.aggregate_code_counts(file_dicts)

filter_issues_by_severity staticmethod

filter_issues_by_severity(
    issues_list: list[dict], severity: int
) -> list[dict]

Gather all issues matching or below a given severity.

Parameters:

Name Type Description Default
issues_list list[dict]

A list of dictionaries containing the full issue list.

required
severity int

The level of issues to keep.

required

Returns:

Type Description
list[dict]

list[dict]: A list of dictionaries containing the issue list after filtering by severity.

Source code in hed/errors/error_reporter.py
@staticmethod
def filter_issues_by_severity(issues_list: list[dict], severity: int) -> list[dict]:
    """ Gather all issues matching or below a given severity.

    Parameters:
        issues_list (list[dict]): A list of dictionaries containing the full issue list.
        severity (int): The level of issues to keep.

    Returns:
        list[dict]: A list of dictionaries containing the issue list after filtering by severity.

    """
    return [issue for issue in issues_list if issue['severity'] <= severity]

format_error staticmethod

format_error(
    error_type: str, *args, actual_error=None, **kwargs
) -> list[dict]

Format an error based on the parameters, which vary based on what type of error this is.

Parameters:

Name Type Description Default
error_type str

The type of error for this. Registered with @hed_error or @hed_tag_error.

required
args args

Any remaining non-keyword args after those required by the error type.

()
actual_error str or None

Code to actually add to report out.

None
kwargs kwargs

The other keyword args to pass down to the error handling func.

{}

Returns:

Type Description
list[dict]

list[dict]: A list containing a single dictionary representing a single error.

Notes

The actual error is useful for errors that are shared like invalid character.

Source code in hed/errors/error_reporter.py
@staticmethod
def format_error(error_type: str, *args, actual_error=None, **kwargs) -> list[dict]:
    """ Format an error based on the parameters, which vary based on what type of error this is.

    Parameters:
        error_type (str): The type of error for this. Registered with @hed_error or @hed_tag_error.
        args (args): Any remaining non-keyword args after those required by the error type.
        actual_error (str or None): Code to actually add to report out.
        kwargs (kwargs): The other keyword args to pass down to the error handling func.

    Returns:
        list[dict]: A list containing a single dictionary representing a single error.

    Notes:
        The actual error is useful for errors that are shared like invalid character.

    """
    error_func = error_functions.get(error_type)
    if not error_func:
        error_object = ErrorHandler.val_error_unknown(*args, **kwargs)
        error_object['code'] = error_type
    else:
        error_object = error_func(*args, **kwargs)

    if actual_error:
        error_object['code'] = actual_error

    return [error_object]

format_error_from_context staticmethod

format_error_from_context(
    error_type: str,
    error_context: list,
    *args,
    actual_error: Optional[str],
    **kwargs
) -> list[dict]

Format an error based on the error type.

Parameters:

Name Type Description Default
error_type str

The type of error. Registered with @hed_error or @hed_tag_error.

required
error_context list

Contains the error context to use for this error.

required
args args

Any remaining non-keyword args.

()
actual_error str or None

Error code to actually add to report out.

required
kwargs kwargs

Keyword parameters to pass down to the error handling func.

{}

Returns:

Type Description
list[dict]

list[dict]: A list containing a single dictionary.

Notes
  • Generally the error_context is returned from _add_context_to_error.
  • The actual_error is useful for errors that are shared like invalid character.
  • This can't filter out warnings like the other ones.
Source code in hed/errors/error_reporter.py
@staticmethod
def format_error_from_context(error_type: str, error_context: list, *args, actual_error: Optional[str], **kwargs) -> list[dict]:
    """ Format an error based on the error type.

    Parameters:
        error_type (str): The type of error. Registered with @hed_error or @hed_tag_error.
        error_context (list): Contains the error context to use for this error.
        args (args): Any remaining non-keyword args.
        actual_error (str or None): Error code to actually add to report out.
        kwargs (kwargs): Keyword parameters to pass down to the error handling func.

    Returns:
        list[dict]: A list containing a single dictionary.

    Notes:
        - Generally the error_context is returned from _add_context_to_error.
        - The actual_error is useful for errors that are shared like invalid character.
        - This can't filter out warnings like the other ones.

    """
    error_list = ErrorHandler.format_error(error_type, *args, actual_error=actual_error, **kwargs)

    ErrorHandler._add_context_to_error(error_list[0], error_context)
    ErrorHandler._update_error_with_char_pos(error_list[0])
    return error_list

pop_error_context

pop_error_context()

Remove the last scope from the error context.

Notes

Modifies the error context of this reporter.

Source code in hed/errors/error_reporter.py
def pop_error_context(self):
    """ Remove the last scope from the error context.

    Notes:
        Modifies the error context of this reporter.

    """

    self.error_context.pop(-1)

push_error_context

push_error_context(context_type, context)

Push a new error context to narrow down error scope.

Parameters:

Name Type Description Default
context_type str

A value from ErrorContext representing the type of scope.

required
context str, int, or HedString

The main value for the context_type.

required
Notes

The context depends on the context_type. For ErrorContext.FILE_NAME this would be the actual filename.

Source code in hed/errors/error_reporter.py
def push_error_context(self, context_type, context):
    """ Push a new error context to narrow down error scope.

    Parameters:
        context_type (str): A value from ErrorContext representing the type of scope.
        context (str, int, or HedString): The main value for the context_type.

    Notes:
        The context depends on the context_type. For ErrorContext.FILE_NAME this would be the actual filename.

    """
    if context is None:
        if context_type in int_sort_list:
            context = 0
        else:
            context = ""
    self.error_context.append((context_type, context))

reset_error_context

reset_error_context()

Reset all error context information to defaults.

Notes

This function is mainly for testing and should not be needed with proper usage.

Source code in hed/errors/error_reporter.py
def reset_error_context(self):
    """ Reset all error context information to defaults.

    Notes:
        This function is mainly for testing and should not be needed with proper usage.

    """
    self.error_context = []

val_error_unknown

val_error_unknown(*args, **kwargs) -> str

Default error handler if no error of this type was registered.

Parameters:

Name Type Description Default
args args

List of non-keyword parameters (varies).

()
kwargs kwargs

Keyword parameters (varies)

{}

Returns:

Name Type Description
str str

The error message.

Source code in hed/errors/error_reporter.py
@hed_error("Unknown")
def val_error_unknown(*args, **kwargs) -> str:
    """ Default error handler if no error of this type was registered.

    Parameters:
        args (args): List of non-keyword parameters (varies).
        kwargs (kwargs): Keyword parameters (varies)

    Returns:
        str: The error message.

    """
    return f"Unknown error. Args: {str(args), str(kwargs)}"

ErrorContext

ErrorContext

Context this error took place in, each error potentially having multiple contexts.

Source code in hed/errors/error_types.py
class ErrorContext:
    """Context this error took place in, each error potentially having multiple contexts. """
    # Use this one to display any passed in message without modification
    CUSTOM_TITLE = 'ec_title'
    FILE_NAME = 'ec_filename'
    SIDECAR_COLUMN_NAME = 'ec_sidecarColumnName'
    SIDECAR_KEY_NAME = 'ec_sidecarKeyName'
    ROW = 'ec_row'
    COLUMN = 'ec_column'
    LINE = "ec_line"
    HED_STRING = 'ec_HedString'
    SCHEMA_SECTION = 'ec_section'
    SCHEMA_TAG = 'ec_schema_tag'
    SCHEMA_ATTRIBUTE = 'ec_attribute'

Error Types

ErrorSeverity

ErrorSeverity

Severity codes for errors

Source code in hed/errors/error_types.py
4
5
6
7
class ErrorSeverity:
    """Severity codes for errors"""
    ERROR = 1
    WARNING = 10

ValidationErrors

ValidationErrors

Source code in hed/errors/error_types.py
class ValidationErrors:
    # General validation errors.
    CHARACTER_INVALID = 'CHARACTER_INVALID'
    COMMA_MISSING = 'COMMA_MISSING'
    DEF_EXPAND_INVALID = "DEF_EXPAND_INVALID"
    DEF_INVALID = "DEF_INVALID"
    DEFINITION_INVALID = "DEFINITION_INVALID"
    ELEMENT_DEPRECATED = "ELEMENT_DEPRECATED"
    TEMPORAL_TAG_ERROR = 'TEMPORAL_TAG_ERROR'
    PARENTHESES_MISMATCH = 'PARENTHESES_MISMATCH'
    PLACEHOLDER_INVALID = 'PLACEHOLDER_INVALID'
    REQUIRED_TAG_MISSING = 'REQUIRED_TAG_MISSING'
    SIDECAR_INVALID = 'SIDECAR_INVALID'
    SIDECAR_KEY_MISSING = 'SIDECAR_KEY_MISSING'
    HED_COLUMN_MISSING = 'HED_COLUMN_MISSING'
    STYLE_WARNING = "STYLE_WARNING"
    TAG_EMPTY = 'TAG_EMPTY'
    TAG_EXPRESSION_REPEATED = 'TAG_EXPRESSION_REPEATED'
    TAG_EXTENDED = 'TAG_EXTENDED'
    TAG_EXTENSION_INVALID = 'TAG_EXTENSION_INVALID'
    TAG_GROUP_ERROR = "TAG_GROUP_ERROR"
    TAG_INVALID = "TAG_INVALID"
    TAG_NOT_UNIQUE = 'TAG_NOT_UNIQUE'
    TAG_NAMESPACE_PREFIX_INVALID = 'TAG_NAMESPACE_PREFIX_INVALID'
    TAG_REQUIRES_CHILD = 'TAG_REQUIRES_CHILD'
    TILDES_UNSUPPORTED = 'TILDES_UNSUPPORTED'
    UNITS_INVALID = 'UNITS_INVALID'
    VERSION_DEPRECATED = 'VERSION_DEPRECATED'
    VALUE_INVALID = 'VALUE_INVALID'

    # Internal codes
    HED_DEF_UNMATCHED = "HED_DEF_UNMATCHED"
    HED_DEF_VALUE_MISSING = "HED_DEF_VALUE_MISSING"
    HED_DEF_VALUE_EXTRA = "HED_DEF_VALUE_EXTRA"

    HED_DEF_EXPAND_INVALID = "HED_DEF_EXPAND_INVALID"
    HED_DEF_EXPAND_UNMATCHED = "HED_DEF_EXPAND_UNMATCHED"
    HED_DEF_EXPAND_VALUE_MISSING = "HED_DEF_EXPAND_VALUE_MISSING"
    HED_DEF_EXPAND_VALUE_EXTRA = "HED_DEF_EXPAND_VALUE_EXTRA"

    HED_RESERVED_TAG_REPEATED = 'HED_RESERVED_TAG_REPEATED'
    HED_RESERVED_TAG_GROUP_ERROR = 'HED_RESERVED_TAG_GROUP_ERROR'
    HED_TAG_REPEATED = 'HED_TAG_REPEATED'
    HED_TAG_REPEATED_GROUP = 'HED_TAG_REPEATED_GROUP'

    INVALID_PARENT_NODE = "invalidParent"
    NO_VALID_TAG_FOUND = "invalidTag"
    NODE_NAME_EMPTY = 'NODE_NAME_EMPTY'

    HED_LIBRARY_UNMATCHED = "HED_LIBRARY_UNMATCHED"
    HED_TOP_LEVEL_TAG = "HED_TOP_LEVEL_TAG"
    HED_MULTIPLE_TOP_TAGS = "HED_MULTIPLE_TOP_TAGS"
    HED_TAG_GROUP_TAG = "HED_TAG_GROUP_TAG"
    HED_TAGS_NOT_ALLOWED = "HED_TAGS_NOT_ALLOWED"

    HED_GROUP_EMPTY = 'HED_GROUP_EMPTY'
    # end internal codes

    # Still being worked on below this line
    HED_MISSING_REQUIRED_COLUMN = "HED_MISSING_REQUIRED_COLUMN"
    HED_UNKNOWN_COLUMN = "HED_UNKNOWN_COLUMN"
    SIDECAR_AND_OTHER_COLUMNS = "SIDECAR_AND_OTHER_COLUMNS"

    DUPLICATE_COLUMN_IN_LIST = "DUPLICATE_COLUMN_IN_LIST"
    DUPLICATE_COLUMN_BETWEEN_SOURCES = "DUPLICATE_COLUMN_BETWEEN_SOURCES"
    HED_BLANK_COLUMN = "HED_BLANK_COLUMN"

    INVALID_VALUE_CLASS_CHARACTER = 'INVALID_VALUE_CLASS_CHARACTER'
    INVALID_VALUE_CLASS_VALUE = 'INVALID_VALUE_CLASS_VALUE'
    INVALID_TAG_CHARACTER = 'invalidTagCharacter'

    HED_PLACEHOLDER_OUT_OF_CONTEXT = 'HED_PLACEHOLDER_OUT_OF_CONTEXT'
    CURLY_BRACE_UNSUPPORTED_HERE = 'CURLY_BRACE_UNSUPPORTED_HERE'
    ONSETS_UNORDERED = "ONSETS_UNORDERED"
    TSV_COLUMN_MISSING="TSV_COLUMN_MISSING"

SidecarErrors

SidecarErrors

Source code in hed/errors/error_types.py
class SidecarErrors:
    # These are for json sidecar validation errors(sidecars can also produce most normal validation errors)
    BLANK_HED_STRING = 'blankValueString'
    WRONG_HED_DATA_TYPE = 'wrongHedDataType'
    INVALID_POUND_SIGNS_VALUE = 'invalidNumberPoundSigns'
    INVALID_POUND_SIGNS_CATEGORY = 'tooManyPoundSigns'
    UNKNOWN_COLUMN_TYPE = 'sidecarUnknownColumn'
    SIDECAR_HED_USED = 'SIDECAR_HED_USED'
    SIDECAR_NA_USED = 'SIDECAR_NA_USED'
    SIDECAR_BRACES_INVALID = "SIDECAR_BRACES_INVALID"

Schema Error Messages

schema_error_messages

Format templates for HED schema error messages.