nodejs/node · error · ValueError
Unsupported type when printing to GN.
Error message
Unsupported type when printing to GN.
What it means
ValueError raised by GenerateTokens for any value type it does not support: only dicts, lists, strings, ints, and bools are handled; the else branch (which the comment notes also excludes float) raises this. It is the catch-all for values the GN printer cannot serialize.
Source
Thrown at tools/gypi_to_gn.py:160
yield ']'
elif isinstance(v, dict):
if level > 0:
yield '{'
for key in sorted(v):
if not isinstance(key, str):
raise ValueError('Dictionary key is not a string.')
if not key or key[0].isdigit() or not key.replace('_', '').isalnum():
raise ValueError('Dictionary key is not a valid GN identifier.')
yield key # No quotations.
yield '='
for tok in GenerateTokens(v[key], level + 1):
yield tok
if level > 0:
yield '}'
else: # Not supporting float: Add only when needed.
raise ValueError('Unsupported type when printing to GN.')
can_start = lambda tok: tok and tok not in ',}]='
can_end = lambda tok: tok and tok not in ',{[='
# Adds whitespaces, trying to keep everything (except dicts) in 1 line.
def PlainGlue(gen):
prev_tok = None
for i, tok in enumerate(gen):
if i > 0:
if can_end(prev_tok) and can_start(tok):
yield '\n' # New dict item.
elif prev_tok == '[' and tok == ']':
yield ' ' # Special case for [].
elif tok != ',':
yield ' '
yield tok
prev_tok = tok
View on GitHub (pinned to 1b2de5e052)
Solutions
- Convert unsupported values to supported types before generation: floats to strings or ints, None to an empty string or omit, tuples to lists.
- Extend the handling chain (str, int, bool, list, dict) explicitly for the new type if floats are genuinely needed (the comment invites this).
- Validate the data structure recursively and reject/transform unsupported types up front.
Example fix
# before
data = {'threshold': 0.5} # float -> raises
# after
data = {'threshold': '0.5'} # string is supported Defensive patterns
Strategy: type-guard
Validate before calling
ALLOWED = (dict, list, str, int, bool)
def is_supported_value(obj) -> bool:
if isinstance(obj, (str, int, bool)):
return True
if isinstance(obj, dict):
return all(is_supported_value(v) for v in obj.values())
if isinstance(obj, list):
return all(is_supported_value(i) for i in obj)
return False Type guard
def is_gn_primitive(v) -> bool:
return isinstance(v, (str, int, bool, list, dict)) Try / catch
try:
list(GenerateTokens(data))
except ValueError as e:
if 'Unsupported type' in str(e):
pass # convert floats/None/tuples to supported types, retry Prevention
- Convert floats to str/int and None to '' before conversion.
- Recursive-walk the data to verify only supported types remain.
- Extend the handler chain if a new primitive type is genuinely needed.
When it happens
Trigger: Passing a structure containing a float, None, tuple, set, custom object, or any non-primitive to GenerateTokens.
Common situations: GYP data containing floating-point values (e.g. version numbers as floats), None values from optional fields, or tuples introduced by preprocessing.
Related errors
- Dictionary key is not a string.
- --depfile requires --stamp and vice versa
- --depfile requires --stamp and vice versa
- Dictionary key is not a valid GN identifier.
- Invalid config specified via --build: %s
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/b1504ba487e15756.
Report an issue: GitHub.