nodejs/node · error · TypeError

Attempt to merge list item of unsupported type {item.__class

Error message

Attempt to merge list item of unsupported type {item.__class__.__name__}

What it means

MergeLists accepts only three item shapes: str/int primitives (handled first), dict (recursed via MergeDicts), and list (recursed via MergeLists). The final else branch raises TypeError for anything else. Note type(item) in (str,int) is an EXACT type test, so bool (type bool, subclass of int) is NOT matched and will also fall through to this error, as will None, float, tuple, set, and custom objects.

Source

Thrown at tools/gyp/pylib/gyp/input.py:2244

                # only appear once in a list, to be enforced by the list merge append
                # or prepend.
                singleton = True
        elif isinstance(item, dict):
            # Make a copy of the dictionary, continuing to look for paths to fix.
            # The other intelligent aspects of merge processing won't apply because
            # item is being merged into an empty dict.
            to_item = {}
            MergeDicts(to_item, item, to_file, fro_file)
        elif isinstance(item, list):
            # Recurse, making a copy of the list.  If the list contains any
            # descendant dicts, path fixing will occur.  Note that here, custom
            # values for is_paths and append are dropped; those are only to be
            # applied to |to| and |fro|, not sublists of |fro|.  append shouldn't
            # matter anyway because the new |to_item| list is empty.
            to_item = []
            MergeLists(to_item, item, to_file, fro_file)
        else:
            raise TypeError(
                "Attempt to merge list item of unsupported type "
                + item.__class__.__name__
            )

        if append:
            # If appending a singleton that's already in the list, don't append.
            # This ensures that the earliest occurrence of the item will stay put.
            if not singleton or not is_in_set_or_list(to_item, hashable_to_set, to):
                to.append(to_item)
                if is_hashable(to_item):
                    hashable_to_set.add(to_item)
        else:
            # If prepending a singleton that's already in the list, remove the
            # existing instance and proceed with the prepend.  This ensures that the
            # item appears at the earliest possible position in the list.
            while singleton and to_item in to:
                to.remove(to_item)

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Ensure every element in list-valued .gyp keys is a string, int, dict, or list.
  2. Replace None-producing variable expansions with a default string or omit them.
  3. Convert floats/booleans to strings explicitly before they reach gyp.
  4. Audit custom generators that populate list fields.

Example fix

// before: 'defines': ['FOO', None, 1.5]
// after: 'defines': ['FOO', 'BAR', '15']
Defensive patterns

Strategy: type-guard

Validate before calling

def clean_list(lst):
    out = []
    for x in lst:
        if type(x) in (str, int) and type(x) is not bool:
            out.append(x)
        elif isinstance(x, (dict, list)):
            out.append(x)
        else:
            raise TypeError('unsupported list item: %r' % x)
    return out

Type guard

def is_mergeable_item(x): return (type(x) in (str, int) and type(x) is not bool) or isinstance(x, (dict, list))

Try / catch

try:
    MergeLists(to, fro, to_file, fro_file)
except TypeError as e:
    if 'unsupported type' in str(e): print('Sanitize list values to str/int/dict/list'); raise

Prevention

When it happens

Trigger: During a list merge (MergeLists), an element of the 'fro' list is a type other than str/int/dict/list — e.g. None (often from an empty variable expansion), a float, a tuple, a set, a bool, or a user-defined object.

Common situations: A variable expansion that yields None inserted into a sources/defines list; a generator injecting non-primitive objects; JSON/eval producing floats or tuples; booleans used as flags inside list-valued keys.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/cd68a3a27c1661fa. Report an issue: GitHub.