{"record":{"id":"41abd897a2ceb196","repo":"nodejs/node","slug":"addfileconfig-file-s-not-in-project","errorCode":null,"errorMessage":"AddFileConfig: file \"%s\" not in project.","messagePattern":"AddFileConfig: file \"(.+?)\" not in project\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/MSVSProject.py","lineNumber":180,"sourceCode":"        # TODO(rspangler) This also doesn't handle adding files to an existing\n        # filter.  That is, it doesn't merge the trees.\n\n    def AddFileConfig(self, path, config, attrs=None, tools=None):\n        \"\"\"Adds a configuration to a file.\n\n        Args:\n          path: Relative path to the file.\n          config: Name of configuration to add.\n          attrs: Dict of configuration attributes; may be None.\n          tools: List of tools (strings or Tool objects); may be None.\n\n        Raises:\n          ValueError: Relative path does not match any file added via AddFiles().\n        \"\"\"\n        # Find the file node with the right relative path\n        parent = self.files_dict.get(path)\n        if not parent:\n            raise ValueError('AddFileConfig: file \"%s\" not in project.' % path)\n\n        # Add the config to the file node\n        spec = self._GetSpecForConfiguration(\"FileConfiguration\", config, attrs, tools)\n        parent.append(spec)\n\n    def WriteIfChanged(self):\n        \"\"\"Writes the project file.\"\"\"\n        # First create XML content definition\n        content = [\n            \"VisualStudioProject\",\n            {\n                \"ProjectType\": \"Visual C++\",\n                \"Version\": self.version.ProjectVersion(),\n                \"Name\": self.name,\n                \"ProjectGUID\": self.guid,\n                \"RootNamespace\": self.name,\n                \"Keyword\": \"Win32Proj\",\n            },","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/MSVSProject.py#L162-L198","documentation":"MSVSProject.AddFileConfig raises ValueError when the given relative path is not present in self.files_dict. The VisualStudioProject object only knows about files previously registered through AddFiles(); AddFileConfig is meant to attach a per-configuration FileConfiguration to an already-known file node. Passing a path that was never added (or that doesn't byte-match the stored key) is treated as a programming error in the project generation pipeline.","triggerScenarios":"Calling proj.AddFileConfig(path, config, ...) before a corresponding proj.AddFiles([path]) for the exact same path string; using a path with a different separator ('\\\\' vs '/') or different casing than what AddFiles stored; removing a file from the spec then trying to configure it.","commonSituations":"Gyp emits an MSVS project and a generator/extension tries to set per-config attributes on a file that was filtered out of AddFiles (excluded by sources! rules); cross-platform path joining produces 'foo\\bar.cpp' for AddFiles and 'foo/bar.cpp' for AddFileConfig.","solutions":["Call AddFiles([path]) with the identical path string before AddFileConfig(path, ...).","Normalize both paths the same way (os.path.normpath or the project's existing helper) before lookup.","Audit gyp source rules to confirm the file isn't being filtered out by 'sources!' exclusions before AddFileConfig runs.","If the file is intentionally absent, skip the AddFileConfig call rather than configuring a phantom node."],"exampleFix":"# before\nproj.AddFileConfig('src/foo.cpp', 'Debug', attrs, tools)\n\n# after\nproj.AddFiles(['src/foo.cpp'])\nproj.AddFileConfig('src/foo.cpp', 'Debug', attrs, tools)","handlingStrategy":"validation","validationCode":"def safe_add_file_config(proj, path, config, attrs=None, tools=None):\n    norm = os.path.normpath(path)\n    if norm not in proj.files_dict:\n        proj.AddFiles([norm])\n    proj.AddFileConfig(norm, config, attrs, tools)","typeGuard":"def file_is_known(proj, path: str) -> bool:\n    return os.path.normpath(path) in proj.files_dict","tryCatchPattern":"from gyp.MSVSProject import MSVSProject\ntry:\n    proj.AddFileConfig(path, config, attrs, tools)\nexcept ValueError:\n    # file not added via AddFiles yet -> add then retry\n    proj.AddFiles([path])\n    proj.AddFileConfig(path, config, attrs, tools)","preventionTips":["Always call AddFiles([path]) with the exact string before AddFileConfig(path, ...).","Normalize paths with the project's own helper so separators/casing match the stored key.","Treat AddFileConfig as a per-config decorator on files already in the project, never as an inserter."],"tags":["gyp","msvs","visual-studio","project-generation","validation"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}