{"record":{"id":"cb879e1fc33d59de","repo":"nodejs/node","slug":"name-key-excluded-key-must-not-be-present-prio","errorCode":null,"errorMessage":"{name} key {excluded_key} must not be present prior  to applying exclusion/regex filters for {list_key}","messagePattern":"(.+?) key (.+?) must not be present prior  to applying exclusion/regex filters for (.+?)","errorType":"exception","errorClass":"GypError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/input.py","lineNumber":2632,"sourceCode":"                        # Even if the regex matches, nothing will change so continue\n                        # (regex searches are expensive).\n                        continue\n                    if pattern_re.search(list_item):\n                        # Regular expression match.\n                        list_actions[index] = action_value\n\n            # The \"whatever/\" list is no longer needed, dump it.\n            del the_dict[regex_key]\n\n        # Add excluded items to the excluded list.\n        #\n        # Note that exclude_key (\"sources!\") is different from excluded_key\n        # (\"sources_excluded\").  The exclude_key list is input and it was already\n        # processed and deleted; the excluded_key list is output and it's about\n        # to be created.\n        excluded_key = list_key + \"_excluded\"\n        if excluded_key in the_dict:\n            raise GypError(\n                name + \" key \" + excluded_key + \" must not be present prior \"\n                \" to applying exclusion/regex filters for \" + list_key\n            )\n\n        excluded_list = []\n\n        # Go backwards through the list_actions list so that as items are deleted,\n        # the indices of items that haven't been seen yet don't shift.  That means\n        # that things need to be prepended to excluded_list to maintain them in the\n        # same order that they existed in the_list.\n        for index in range(len(list_actions) - 1, -1, -1):\n            if list_actions[index] == 0:\n                # Dump anything with action 0 (exclude).  Keep anything with action 1\n                # (include) or -1 (no include or exclude seen for the item).\n                excluded_list.insert(0, the_list[index])\n                del the_list[index]\n\n        # If anything was excluded, put the excluded list into the_dict at","sourceCodeStart":2614,"sourceCodeEnd":2650,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/input.py#L2614-L2650","documentation":"After applying exclusion/regex filters, gyp creates an output list named '<list_key>_excluded' (e.g. 'sources_excluded'). If that output key ALREADY exists in the dict before filtering, gyp raises GypError because it would clobber user data / indicate a double-processing mistake.","triggerScenarios":"the_dict already contains a key like 'sources_excluded' at the moment ProcessListFiltersInDict runs for the matching 'sources'/'sources!' pair.","commonSituations":"Manually pre-declaring 'sources_excluded' thinking it is input; running the filter pass twice on the same dict; an include file that ships a pre-built excluded list; merging artifacts from a prior partial run.","solutions":["Remove the pre-existing '_excluded' key; it is generated output, not input.","Do not declare 'sources_excluded' (or any '<key>_excluded') by hand.","Ensure the filter pass is invoked once per dict (avoid double processing)."],"exampleFix":"// before: { 'sources': [...], 'sources!': [...], 'sources_excluded': [...] }\n// after: { 'sources': [...], 'sources!': [...] }  // gyp creates sources_excluded","handlingStrategy":"validation","validationCode":"for k in list(the_dict):\n    if k[-1:] in ('!', '/'):\n        base = k[:-1]\n        assert (base + '_excluded') not in the_dict, 'pre-existing %s_excluded' % base\n","typeGuard":null,"tryCatchPattern":"try:\n    gyp.main(args)\nexcept gyp.input.GypError as e:\n    if 'must not be present prior' in str(e): print('Remove the hand-written _excluded key'); raise","preventionTips":["Never declare '<key>_excluded' manually; it is generated output.","Run the filter pass once per dict.","Audit includes for stale excluded lists."],"tags":["gyp","list-filter","validation","build-config"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}