nodejs/node · error · GypError
%s does not evaluate to a dictionary.
Error message
%s does not evaluate to a dictionary.
What it means
Raised as a GypError by LoadOneBuildFile after a .gyp file is read and evaluated but the resulting top-level value is not a dictionary. A .gyp file must evaluate to a dict (with keys like 'targets', 'includes', 'variables'); any other top-level expression is a structural error.
Source
Thrown at tools/gyp/pylib/gyp/input.py:246
build_file_contents = open(build_file_path, encoding="utf-8").read()
else:
raise GypError(f"{build_file_path} not found (cwd: {os.getcwd()})")
build_file_data = None
try:
if check:
build_file_data = CheckedEval(build_file_contents)
else:
build_file_data = eval(build_file_contents, {"__builtins__": {}}, None)
except SyntaxError as e:
e.filename = build_file_path
raise
except Exception as e:
gyp.common.ExceptionAppend(e, "while reading " + build_file_path)
raise
if not isinstance(build_file_data, dict):
raise GypError("%s does not evaluate to a dictionary." % build_file_path)
data[build_file_path] = build_file_data
aux_data[build_file_path] = {}
# Scan for includes and merge them in.
if "skip_includes" not in build_file_data or not build_file_data["skip_includes"]:
try:
if is_target:
LoadBuildFileIncludesIntoDict(
build_file_data, build_file_path, data, aux_data, includes, check
)
else:
LoadBuildFileIncludesIntoDict(
build_file_data, build_file_path, data, aux_data, None, check
)
except Exception as e:
gyp.common.ExceptionAppend(
e, "while reading includes of " + build_file_pathView on GitHub (pinned to 1b2de5e052)
Solutions
- Ensure the .gyp file's top-level construct is a dict literal, e.g. { 'targets': [ ... ] }.
- If the file contains a bare list, wrap it as { 'targets': <that list> }.
- Validate the file evaluates to a dict before running gyp (e.g. a quick AST/eval check).
Example fix
// before (foo.gyp)
[ { 'target_name': 'foo', 'type': 'none' } ]
// after
{
'targets': [
{ 'target_name': 'foo', 'type': 'none' }
]
} Defensive patterns
Strategy: validation
Validate before calling
data = eval(open('foo.gyp').read(), {'__builtins__': {}}, None)
if not isinstance(data, dict):
raise ValueError('foo.gyp must evaluate to a dictionary') Type guard
def evaluates_to_dict(data) -> bool:
return isinstance(data, dict) Prevention
- Ensure every .gyp file's top-level construct is a dict literal.
- Start new .gyp files from a template with the correct root structure.
When it happens
Trigger: A .gyp file whose top-level expression is not a dict — e.g. a bare list, a string, or an expression statement. After eval, isinstance(build_file_data, dict) is False at input.py:248.
Common situations: A .gyp file containing only a list of targets instead of { 'targets': [...] }; a file reduced to a bare expression by a bad edit; accidentally creating a .gyp from a template that outputs the wrong root structure.
Related errors
- Unable to find targets in build file %s
- Key '%s' repeated at level %s with key path '%s'
- %s must not contain included_files key
- Unable to open file %s
- config_path must be a JSON file containing a dictionary
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/92ddb92cb7b3e61c.
Report an issue: GitHub.