nodejs/node · error · Exception
Invalid suite configuration.%s
Error message
Invalid suite configuration.%s
What it means
Thrown by MakeGraphConfig in run_perf.py when a suite dict contains neither a 'main' key nor a 'tests' key, so the builder cannot decide whether the node is runnable, a graph, or a leaf. It is marked '# pragma: no cover' because the surrounding branches are expected to catch all valid combinations, so hitting it means the suite dict is structurally malformed.
Source
Thrown at deps/v8/tools/run_perf.py:656
def GetGraphConfigClass(suite, parent):
"""Factory method for making graph configuration objects."""
if isinstance(parent, TraceConfig):
if suite.get("tests"):
return TraceConfig
return LeafTraceConfig
elif suite.get('main') is not None:
# A main file makes this graph runnable. Empty strings are accepted.
if suite.get('tests'):
# This graph has subgraphs (traces).
return RunnableConfig
else:
# This graph has no subgraphs, it's a leaf.
return RunnableLeafTraceConfig
elif suite.get('tests'):
# This is neither a leaf nor a runnable.
return GraphConfig
else: # pragma: no cover
raise Exception('Invalid suite configuration.' + str(suite)[:200])
def BuildGraphConfigs(suite, parent, arch):
"""Builds a tree structure of graph objects that corresponds to the suite
configuration.
- GraphConfig:
- Can have arbitrary children
- can be used to store properties used by its children
- VariantConfig
- Has variants of the same (any) type as children
For all other configs see the override AppendChild methods.
Example 1:
- GraphConfig
- RunnableLeafTraceConfig (no children)View on GitHub (pinned to 1b2de5e052)
Solutions
- Open the suite JSON named on the command line and find the node with neither 'main' nor 'tests'; add the missing key.
- If the node is meant to be a pure grouping node, give it a 'tests' array; if it should run a script, add 'main'.
- Re-run with the same JSON and confirm MakeGraphConfig now returns a concrete class (RunnableConfig / GraphConfig / LeafTraceConfig).
Example fix
// before
{ "name":"group" }
// after
{ "name":"group", "tests": [] } Defensive patterns
Strategy: validation
Validate before calling
def validate_suite(suite):
if 'main' not in suite and 'tests' not in suite:
raise ValueError(f"Suite {suite.get('name','?')} has neither 'main' nor 'tests'; add one before running run_perf.")
return True Type guard
def is_valid_suite_dict(suite: dict) -> bool:
return isinstance(suite, dict) and ('main' in suite or 'tests' in suite) Try / catch
null
Prevention
- Lint perf suite JSON files in CI for the presence of 'main' or 'tests' on every node.
- Avoid hand-editing benchmark JSON without re-running a dry validation pass.
When it happens
Trigger: A suite configuration entry missing both 'main' and 'tests' keys reaches MakeGraphConfig. This is only reachable if an upstream guard (which normally rejects keyless suites) is bypassed or if a suite file is hand-edited to drop both fields.
Common situations: Hand-editing a V8 perf benchmark JSON and deleting the 'tests' array from a node that had no 'main'; or a YAML->JSON conversion / templating step that stripped empty keys.
Related errors
- %s only allows TraceConfig and LeafTraceConfig as child conf
- Invalid suite configuration.
- Present value is %s
- CPU cores have differing governor settings
- Could not set CPU governor. Present value is %s
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/e7b309c4d154b604.
Report an issue: GitHub.