nodejs/node · error · TypeError

Attempt to merge dict value of type {v.__class__.__name__} i

Error message

Attempt to merge dict value of type {v.__class__.__name__} into incompatible type {to[list_base].__class__.__name__} for key {list_base}({k})

What it means

A companion to error 509 for list-suffixed keys: when merging a suffixed list key (e.g. 'sources+') into destination 'to', the base key (e.g. 'sources') must already be a list if present. If to[list_base] exists but is not a list (e.g. it is a string), MergeDicts raises TypeError naming the value type, the existing type, and both the base and suffixed key.

Source

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

            # Some combinations of merge policies appearing together are meaningless.
            # It's stupid to replace and append simultaneously, for example.  Append
            # and prepend are the only policies that can coexist.
            for list_incompatible in lists_incompatible:
                if list_incompatible in fro:
                    raise GypError(
                        "Incompatible list policies " + k + " and " + list_incompatible
                    )

            if list_base in to:
                if ext == "?":
                    # If the key ends in "?", the list will only be merged if it doesn't
                    # already exist.
                    continue
                elif not isinstance(to[list_base], list):
                    # This may not have been checked above if merging in a list with an
                    # extension character.
                    raise TypeError(
                        "Attempt to merge dict value of type "
                        + v.__class__.__name__
                        + " into incompatible type "
                        + to[list_base].__class__.__name__
                        + " for key "
                        + list_base
                        + "("
                        + k
                        + ")"
                    )
            else:
                to[list_base] = []

            # Call MergeLists, which will make copies of objects that require it.
            # MergeLists can recurse back into MergeDicts, although this will be
            # to make copies of dicts (with paths fixed), there will be no
            # subsequent dict "merging" once entering a list because lists are
            # always replaced, appended to, or prepended to.

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Ensure to[list_base] is a list whenever you also use a suffixed variant of that key.
  2. Convert the scalar to a single-element list, or remove the conflicting entry.
  3. Audit the order of merges that populate 'to'.

Example fix

// before: { 'sources': 'a.cc' } merged with { 'sources+': ['b.cc'] }
// after: { 'sources': ['a.cc'] } merged with { 'sources+': ['b.cc'] }
Defensive patterns

Strategy: type-guard

Validate before calling

for k in list(the_dict):
    if k[-1:] in ('=','?','+'):
        base = k[:-1]
        if base in the_dict and not isinstance(the_dict[base], list):
            raise TypeError('%s must be a list to use %s' % (base, k))

Type guard

def base_is_list(d, suffixed_key): return isinstance(d.get(suffixed_key[:-1]), list)

Try / catch

try:
    MergeDicts(to, fro, to_file, fro_file)
except TypeError as e:
    if 'incompatible type' in str(e) and '(' in str(e): print('Make the base list key an actual list'); raise

Prevention

When it happens

Trigger: The destination dict 'to' has list_base set to a non-list value, and a merge introduces a suffixed variant (k = list_base + '=' / '?' / '+'). Reached after the incompatible-policy check passes.

Common situations: Target defines 'sources' as a string (mistake) while an include merges 'sources+'; configuration inheritance turning a list into a scalar; earlier merge corruption.

Related errors


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