{"record":{"id":"348019137b8ca3af","repo":"nodejs/node","slug":"s-s-must-be-followed-by-a-dictionary-not-s","errorCode":null,"errorMessage":"%s %s must be followed by a dictionary, not %s","messagePattern":"(.+?) (.+?) must be followed by a dictionary, not (.+?)","errorType":"exception","errorClass":"GypError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/input.py","lineNumber":1134,"sourceCode":"        raise GypError(conditions_key + \" must be a list\")\n    if len(condition) < 2:\n        # It's possible that condition[0] won't work in which case this\n        # attempt will raise its own IndexError.  That's probably fine.\n        raise GypError(\n            conditions_key\n            + \" \"\n            + condition[0]\n            + \" must be at least length 2, not \"\n            + str(len(condition))\n        )\n\n    i = 0\n    result = None\n    while i < len(condition):\n        cond_expr = condition[i]\n        true_dict = condition[i + 1]\n        if not isinstance(true_dict, dict):\n            raise GypError(\n                f\"{conditions_key} {cond_expr} must be followed by a dictionary, \"\n                f\"not {type(true_dict)}\"\n            )\n        if len(condition) > i + 2 and isinstance(condition[i + 2], dict):\n            false_dict = condition[i + 2]\n            i = i + 3\n            if i != len(condition):\n                raise GypError(\n                    f\"{conditions_key} {cond_expr} has \"\n                    f\"{len(condition) - i} unexpected trailing items\"\n                )\n        else:\n            false_dict = None\n            i = i + 2\n        if result is None:\n            result = EvalSingleCondition(\n                cond_expr, true_dict, false_dict, phase, variables, build_file\n            )","sourceCodeStart":1116,"sourceCodeEnd":1152,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/input.py#L1116-L1152","documentation":"In a condition triple [cond_expr, true_dict, (false_dict)], the element immediately after cond_expr must be a dict — the set of keys merged into the enclosing dict when the condition holds. If that second element is a list, string, or any non-dict, EvalCondition raises this GypError naming conditions_key, the cond_expr, and the offending Python type. The false_dict (third element) is optional and only consumed if it too is a dict.","triggerScenarios":"Writing \"['OS==\\\"mac\\\"', ['IS_MAC']]\" — a list instead of a dict as the true body; putting a bare string or a second condition expression where the true_dict belongs; nesting condition lists flatly instead of grouping them.","commonSituations":"Confusing the condition body with a list of defines; misreading the triple structure and supplying [expr, value, value]; refactoring that moves a list into the wrong slot.","solutions":["Make the second element a dict, e.g. { 'defines': ['IS_MAC'], 'sources': [...] }.","Move list-valued content (defines, sources) inside that dict under the appropriate key.","If you intended a nested condition, place another 'conditions' key inside the true_dict."],"exampleFix":"// before\n'conditions': [ ['OS == \"mac\"', ['IS_MAC']] ],\n// after\n'conditions': [ ['OS == \"mac\"', { 'defines': ['IS_MAC'] }] ],","handlingStrategy":"type-guard","validationCode":"def validate_condition(entry, key='conditions'):\n    assert isinstance(entry, list) and len(entry) >= 2\n    assert isinstance(entry[1], dict), \\\n        f'{key} {entry[0]!r} true branch must be a dict, got {type(entry[1]).__name__}'","typeGuard":"def true_branch_is_dict(entry) -> bool:\n    return isinstance(entry, list) and len(entry) >= 2 and isinstance(entry[1], dict)","tryCatchPattern":null,"preventionTips":["Place keys like 'defines'/'sources' inside the true_dict, not as a bare list at index 1.","When refactoring, double-check the second slot of every condition triple."],"tags":["gyp","conditions","syntax","type-check","build-config"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}