nodejs/node · error · GypError
{conditions_key} {cond_expr} has {len(condition) - i} unexpe
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.
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 naturallyView on GitHub (pinned to 1b2de5e052)
Solutions
- Express additional branches as separate entries in the outer conditions list — each entry is one [expr, true_dict, (false_dict)].
- Remove the trailing elements reported by the count in the message.
- 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
- Express if/elif chains as separate condition entries, not extra items in one entry.
- After pasting a condition triple, trim any duplicated trailing dict.
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
- %s must be a list
- %s %s must be at least length 2, not %s
- %s %s must be followed by a dictionary, not %s
- Unknown command string '%s' in '%s'.
- Variable expansion in this context permits str and int only,
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/b3641ab627bbb29d.
Report an issue: GitHub.