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 {expanded.__class__.__name__} for {key} What it means
In ProcessVariablesAndConditionsInDict, every string-valued key in the dict (other than 'variables') is run through ExpandVariables. If expansion yields something other than a str or int (e.g. a list, because a <@(...) list expansion was used where a scalar was expected), GYP raises this ValueError naming the type and the offending key. This guards assignment back into the_dict[key] which must stay scalar.
Source
Thrown at tools/gyp/pylib/gyp/input.py:1323
variables[key] = value
# Handle the associated variables dict first, so that any variable
# references within can be resolved prior to using them as variables.
# Pass a copy of the variables dict to avoid having it be tainted.
# Otherwise, it would have extra automatics added for everything that
# should just be an ordinary variable in this scope.
ProcessVariablesAndConditionsInDict(
the_dict["variables"], phase, variables, build_file, "variables"
)
LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key)
for key, value in the_dict.items():
# Skip "variables", which was already processed if present.
if key != "variables" and isinstance(value, str):
expanded = ExpandVariables(value, phase, variables, build_file)
if type(expanded) not in (str, int):
raise ValueError(
"Variable expansion in this context permits str and int "
+ "only, found "
+ expanded.__class__.__name__
+ " for "
+ key
)
the_dict[key] = expanded
# Variable expansion may have resulted in changes to automatics. Reload.
# TODO(mark): Optimization: only reload if no changes were made.
variables = variables_in.copy()
LoadAutomaticVariablesFromDict(variables, the_dict)
LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key)
# Process conditions in this dict. This is done after variable expansion
# so that conditions may take advantage of expanded variables. For example,
# if the_dict contains:
# {'type': '<(library_type)',View on GitHub (pinned to 1b2de5e052)
Solutions
- If the value should be a list, change the key's value to a list literal containing the expansion, e.g. 'sources': ['<@(my_list)'].
- Drop the '@' marker so the expansion yields a scalar: '<(my_scalar)'.
- Confirm the referenced variable actually holds a scalar (str/int) when used in scalar position.
Example fix
// before — list expansion in scalar position 'type': '<@(list_of_types)', // after — use a scalar variable 'type': '<(the_type)',
Defensive patterns
Strategy: type-guard
Validate before calling
for key, value in the_dict.items():
if key != 'variables' and isinstance(value, str):
expanded = ExpandVariables(value, phase, variables, build_file)
assert type(expanded) in (str, int), \
f'{key} expanded to {type(expanded).__name__}; expected str or int in scalar position' Type guard
def is_scalar_value(value) -> bool:
return type(value) in (str, int) Prevention
- Reserve the '@' list-expansion marker for list contexts only.
- Bind scalar keys to scalar variables; bind list keys to lists.
- Review dict values after renaming variables to ensure types still line up.
When it happens
Trigger: A dict key is set to a string like '<@(my_list)' (the @ list-expansion form) but is in scalar position (a dict value, not a list element) so expansion returns a list; a '<(var)' reference resolving to a list assigned to a scalar key.
Common situations: Using the '@' list-expansion marker on a key whose value is not a list context; expecting '<(var)' to coerce a list to a string; copying list-context syntax into a dict-value slot.
Related errors
- Variable %s must expand to a string or list of strings; foun
- Undefined variable %s in %s
- Variable %s must expand to a string or list of strings; list
- Variable expansion in this context permits str and int only,
- Variable expansion in this context permits strings and lists
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/d44cdffbc7aefc9b.
Report an issue: GitHub.