nodejs/node · error · GypError
%s %s must be at least length 2, not %s
Error message
%s %s must be at least length 2, not %s
What it means
Each condition entry must have at least two elements — a cond_expr and a true_dict — so that EvalCondition can index condition[0] and condition[1]. If len(condition) < 2 (e.g. an empty list or a lone expression with no body), GYP raises this GypError, embedding the (possibly empty) condition[0] and the actual length. Note the code comment: if condition[0] itself raises IndexError on an empty list, that bubbles up — also a sign of the same root cause.
Source
Thrown at tools/gyp/pylib/gyp/input.py:1120
output = int(output)
return output
# The same condition is often evaluated over and over again so it
# makes sense to cache as much as possible between evaluations.
cached_conditions_asts = {}
def EvalCondition(condition, conditions_key, phase, variables, build_file):
"""Returns the dict that should be used or None if the result was
that nothing should be used."""
if not isinstance(condition, list):
raise GypError(conditions_key + " must be a list")
if len(condition) < 2:
# It's possible that condition[0] won't work in which case this
# attempt will raise its own IndexError. That's probably fine.
raise GypError(
conditions_key
+ " "
+ condition[0]
+ " 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):View on GitHub (pinned to 1b2de5e052)
Solutions
- Add the required second element — a dict merged in when the condition is true.
- If the condition is intentionally a no-op, remove the whole entry rather than leaving a 1-element list.
- Optionally add a third dict (false_dict) for the else branch.
Example fix
// before
'conditions': [ ['OS == "mac"'] ],
// after
'conditions': [ ['OS == "mac"', { 'defines': ['IS_MAC'] }] ], Defensive patterns
Strategy: validation
Validate before calling
def validate_condition(entry, key='conditions'):
assert isinstance(entry, list) and len(entry) >= 2, \
f'{key} entry {entry!r} must have at least [expr, true_dict]' Type guard
def has_min_length_two(entry) -> bool:
return isinstance(entry, list) and len(entry) >= 2 Prevention
- Always include a true_dict body for each condition expression.
- If a condition is not needed, delete the whole entry.
- Use a structural linter that flags short condition lists.
When it happens
Trigger: Writing "'conditions': [ ['OS==\"mac\"'] ]" with no dict body; an empty condition list "'conditions': [ [] ]"; a generator that emits only the expression half.
Common situations: Truncated copy-paste of a condition; deleting the true_dict during editing and forgetting to restore it; templating that drops the body when a variable is empty.
Related errors
- %s must be a list
- %s %s must be followed by a dictionary, not %s
- {conditions_key} {cond_expr} has {len(condition) - i} unexpe
- 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/e96a9199dddb5e8b.
Report an issue: GitHub.