nodejs/node · error · GypError

has unexpected trailing items

Error message

{conditions_key} {cond_expr} has {len(condition) - i} unexpected trailing items

What it means

When a condition entry has three elements [cond_expr, true_dict, false_dict] (all three present and false_dict a dict), EvalCondition advances its index by 3 and then requires that index to equal the list length. Any extra elements after the false_dict are reported as 'unexpected trailing items' with the count. This catches malformed conditions that tack on additional bare expressions or dicts beyond the standard triple.

Solutions

  1. Express additional branches as separate entries in the outer conditions list — each entry is one [expr, true_dict, (false_dict)].
  2. Remove the trailing elements reported by the count in the message.
  3. For if/elif chains, use nested 'conditions' inside the false_dict.

Example fix

// before
'conditions': [
  ['OS == "mac"', { 'defines': ['M'] }, { 'defines': ['L'] }, 'extra']
],
// after
'conditions': [
  ['OS == "mac"', { 'defines': ['M'] }, { 'defines': ['L'] }]
],
Defensive patterns

Strategy: validation

Validate before calling

def validate_condition(entry, key='conditions'):
    if len(entry) >= 3 and isinstance(entry[2], dict):
        assert len(entry) == 3, \
            f'{key} {entry[0]!r} has unexpected trailing items beyond [expr, true, false]'

Type guard

def has_no_trailing_items(entry) -> bool:
    if isinstance(entry, list) and len(entry) >= 3 and isinstance(entry[2], dict):
        return len(entry) == 3
    return True

Prevention

When it happens

Trigger: Writing "['OS==\"mac\"', {true}, {false}, 'extra']"; chaining multiple cond_exprs in a single list instead of using multiple list entries; copy-paste that duplicated the false_dict.

Common situations: Trying to express if/elif by listing extra items in one condition rather than as separate top-level condition entries; accidental duplicate paste of a dict.

Related errors


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

Appendix: source

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

            + " must be at least length 2, not "
            + str(len(condition))
        )

    i = 0
    result = None
    while i < len(condition):
        cond_expr = condition[i]
        true_dict = condition[i + 1]
        if not isinstance(true_dict, dict):
            raise GypError(
                f"{conditions_key} {cond_expr} must be followed by a dictionary, "
                f"not {type(true_dict)}"
            )
        if len(condition) > i + 2 and isinstance(condition[i + 2], dict):
            false_dict = condition[i + 2]
            i = i + 3
            if i != len(condition):
                raise GypError(
                    f"{conditions_key} {cond_expr} has "
                    f"{len(condition) - i} unexpected trailing items"
                )
        else:
            false_dict = None
            i = i + 2
        if result is None:
            result = EvalSingleCondition(
                cond_expr, true_dict, false_dict, phase, variables, build_file
            )

    return result


def EvalSingleCondition(cond_expr, true_dict, false_dict, phase, variables, build_file):
    """Returns true_dict if cond_expr evaluates to true, and false_dict
    otherwise."""
    # Do expansions on the condition itself.  Since the condition can naturally

View on GitHub (pinned to 1b2de5e052)