nodejs/node · error · ValueError
Variable expansion in this context permits str and int only,
Error message
Variable expansion in this context permits str and int only, found {cond_expr_expanded.__class__.__name__} What it means
Before evaluating a condition expression via Python eval, EvalSingleCondition runs ExpandVariables on the cond_expr and requires the result to be a str or int (the only types compile/eval can meaningfully handle). If expansion produced a list, dict, or other type, GYP raises this ValueError naming the offending class. This protects the subsequent compile() and eval() from receiving an un-evaluatable object.
Source
Thrown at tools/gyp/pylib/gyp/input.py:1166
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
# contain variable references without needing to resort to GYP expansion
# syntax, this is of dubious value for variables, but someone might want to
# use a command expansion directly inside a condition.
cond_expr_expanded = ExpandVariables(cond_expr, phase, variables, build_file)
if type(cond_expr_expanded) not in (str, int):
raise ValueError(
"Variable expansion in this context permits str and int "
+ "only, found "
+ cond_expr_expanded.__class__.__name__
)
try:
if cond_expr_expanded in cached_conditions_asts:
ast_code = cached_conditions_asts[cond_expr_expanded]
else:
ast_code = compile(cond_expr_expanded, "<string>", "eval")
cached_conditions_asts[cond_expr_expanded] = ast_code
env = {"__builtins__": {}, "v": Version}
if eval(ast_code, env, variables):
return true_dict
return false_dict
except SyntaxError as e:
syntax_error = SyntaxError(
"%s while evaluating condition '%s' in %s "View on GitHub (pinned to 1b2de5e052)
Solutions
- Rewrite the condition expression so it expands to a comparable string/int — e.g. compare against a scalar variable: ['<(my_flag) == "1"', {...}].
- If the variable is a list, wrap the comparison in a form that yields a scalar (e.g. count via a <!pymod_do_main helper).
- Ensure the cond_expr is a Python expression string after expansion, not a bare list/dict.
Example fix
// before — my_items is a list, expansion yields a list
'conditions': [ ['<(my_items)', { 'defines': ['HAS_ITEMS'] }] ],
// after — compare a scalar flag
'conditions': [ ['<(use_items) == "1"', { 'defines': ['HAS_ITEMS'] }] ], Defensive patterns
Strategy: type-guard
Validate before calling
expanded = ExpandVariables(cond_expr, phase, variables, build_file)
assert type(expanded) in (str, int), \
f'Condition expression expanded to {type(expanded).__name__}; must be str or int' Type guard
def expands_to_evaluable(cond_expr: str, variables: dict, phase) -> bool:
# heuristic: ensure no bare <@() list marker that would yield a list
return '<@' not in cond_expr and '>@' not in cond_expr and '^@' not in cond_expr Prevention
- Author condition expressions to evaluate to a boolean via scalar comparisons.
- Never use the '@' (list) expansion marker inside a condition expression.
- Confirm referenced variables resolve to scalars, not lists.
When it happens
Trigger: A condition expression that is itself a <(var) reference resolving to a list (e.g. '<(my_list)' where my_list is a list); a condition whose expansion yields a dict; programmatic gyp usage setting the cond_expr to a non-string.
Common situations: Accidentally using a list-valued variable as the entirety of a condition expression; expecting expansion to join a list into a string (it does not in this context); copy-pasting an expansion that yields a list where a boolean expression string was intended.
Related errors
- Variable %s must expand to a string or list of strings; foun
- %s must be a list
- %s %s must be followed by a dictionary, not %s
- Variable expansion in this context permits str and int only,
- Undefined variable %s in %s
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/a1ef8f7b52819071.
Report an issue: GitHub.