{"record":{"id":"33dae54d85edee5e","repo":"nodejs/node","slug":"missing-input-files-s","errorCode":null,"errorMessage":"Missing input files:\n%s","messagePattern":"Missing input files:\n(.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/msvs_emulation.py","lineNumber":1234,"sourceCode":"        cl_paths[arch] = _ExtractCLPath(output)\n    return cl_paths\n\n\ndef VerifyMissingSources(sources, build_dir, generator_flags, gyp_to_ninja):\n    \"\"\"Emulate behavior of msvs_error_on_missing_sources present in the msvs\n    generator: Check that all regular source files, i.e. not created at run time,\n    exist on disk. Missing files cause needless recompilation when building via\n    VS, and we want this check to match for people/bots that build using ninja,\n    so they're not surprised when the VS build fails.\"\"\"\n    if int(generator_flags.get(\"msvs_error_on_missing_sources\", 0)):\n        no_specials = filter(lambda x: \"$\" not in x, sources)\n        relative = [os.path.join(build_dir, gyp_to_ninja(s)) for s in no_specials]\n        missing = [x for x in relative if not os.path.exists(x)]\n        if missing:\n            # They'll look like out\\Release\\..\\..\\stuff\\things.cc, so normalize the\n            # path for a slightly less crazy looking output.\n            cleaned_up = [os.path.normpath(x) for x in missing]\n            raise Exception(\"Missing input files:\\n%s\" % \"\\n\".join(cleaned_up))\n\n\n# Sets some values in default_variables, which are required for many\n# generators, run on Windows.\ndef CalculateCommonVariables(default_variables, params):\n    generator_flags = params.get(\"generator_flags\", {})\n\n    # Set a variable so conditions can be based on msvs_version.\n    msvs_version = gyp.msvs_emulation.GetVSVersion(generator_flags)\n    default_variables[\"MSVS_VERSION\"] = msvs_version.ShortName()\n\n    # To determine processor word size on Windows, in addition to checking\n    # PROCESSOR_ARCHITECTURE (which reflects the word size of the current\n    # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which\n    # contains the actual word size of the system when running thru WOW64).\n    if \"64\" in os.environ.get(\"PROCESSOR_ARCHITECTURE\", \"\") or \"64\" in os.environ.get(\n        \"PROCESSOR_ARCHITEW6432\", \"\"\n    ):","sourceCodeStart":1216,"sourceCodeEnd":1252,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/msvs_emulation.py#L1216-L1252","documentation":"When generator_flags['msvs_error_on_missing_sources'] is set, gyp checks that every regular source file (those without a '$' special marker) exists on disk relative to the build dir. Missing files would cause unnecessary recompilation and confusing VS failures; this opt-in check surfaces them early with a normalized path list.","triggerScenarios":"msvs_error_on_missing_sources is truthy in generator_flags and at least one entry in the target's sources resolves (after gyp_to_ninja and build_dir join) to a path that os.path.exists reports as missing.","commonSituations":"A source file was deleted or moved but not removed from the .gyp file; a generated source listed as a regular source but not yet produced; wrong relative path in sources; building before running a codegen step that creates the file.","solutions":["For each path in the error, verify whether the file should exist at that location.","If it was removed/moved, delete or fix the entry in the .gyp 'sources' list.","If it is a generated file, ensure the generator step runs before this check, or remove the flag for that build.","If paths are relative, correct them so they resolve under the build directory."],"exampleFix":"// before\n'sources': ['src/removed.cc', 'src/main.cc']\n// after\n'sources': ['src/main.cc']","handlingStrategy":"validation","validationCode":"import os\nbuild_dir = '.'\nfor s in target_dict.get('sources', []):\n    if '$' in s:\n        continue\n    if not os.path.exists(os.path.normpath(os.path.join(build_dir, s))):\n        raise FileNotFoundError(f'missing source referenced by {target_dict.get(\"target_name\")}: {s}')","typeGuard":"def all_regular_sources_exist(target_dict: dict, build_dir: str) -> bool:\n    import os\n    for s in target_dict.get('sources', []):\n        if '$' in s:\n            continue\n        if not os.path.exists(os.path.normpath(os.path.join(build_dir, s))):\n            return False\n    return True","tryCatchPattern":null,"preventionTips":["Remove deleted files from .gyp sources immediately.","Only enable msvs_error_on_missing_sources once all sources are stable.","Ensure codegen steps that produce sources run before this check; mark generated sources with '$' where appropriate."],"tags":["gyp","msvs","sources","missing-files"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}