{"record":{"id":"644f1d49515b7324","repo":"nodejs/node","slug":"unknown-command-string-s-in-s","errorCode":null,"errorMessage":"Unknown command string '%s' in '%s'.","messagePattern":"Unknown command string '(.+?)' in '(.+?)'\\.","errorType":"exception","errorClass":"GypError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/input.py","lineNumber":953,"sourceCode":"                    sys.path.append(os.getcwd())\n                    try:\n                        parsed_contents = shlex.split(contents)\n                        try:\n                            py_module = __import__(parsed_contents[0])\n                        except ImportError as e:\n                            raise GypError(\n                                \"Error importing pymod_do_main\"\n                                \"module (%s): %s\" % (parsed_contents[0], e)\n                            )\n                        replacement = str(\n                            py_module.DoMain(parsed_contents[1:])\n                        ).rstrip()\n                    finally:\n                        sys.path.pop()\n                        os.chdir(oldwd)\n                    assert replacement is not None\n                elif command_string:\n                    raise GypError(\n                        \"Unknown command string '%s' in '%s'.\"\n                        % (command_string, contents)\n                    )\n                else:\n                    # Fix up command with platform specific workarounds.\n                    contents = FixupPlatformCommand(contents)\n                    try:\n                        # stderr will be printed no matter what\n                        result = subprocess.run(\n                            contents,\n                            stdout=subprocess.PIPE,\n                            shell=use_shell,\n                            cwd=build_file_dir,\n                            check=False,\n                        )\n                    except Exception as e:\n                        raise GypError(\n                            \"%s while executing command '%s' in %s\"","sourceCodeStart":935,"sourceCodeEnd":971,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/input.py#L935-L971","documentation":"Inside a <! or >! command expansion, GYP recognizes an optional command_string prefix that selects how the command is dispatched. The only supported command_string is 'pymod_do_main'; any other recognized-but-unsupported command_string value raises this GypError listing both the unknown command and the raw contents. This is a parser-level rejection, not a runtime failure of the command itself.","triggerScenarios":"A .gyp file writes something like '<!(myCmd args)' where 'myCmd' is parsed by GYP's regex as a command_string rather than a plain shell command, or the user assumes GYP supports other prefixed commands. Effectively any command_string that isn't 'pymod_do_main' and isn't empty reaches this branch.","commonSituations":"Misreading the GYP docs and inventing a command_string prefix; a stray token before the paren that the regex latches onto as a command_string; copy-paste from a non-GYP build system that uses a different prefix syntax.","solutions":["Remove the unsupported prefix and write the command as a plain shell command '<!(my_cmd args)' instead of '<!(prefix args)'.","If you wanted Python, switch to the supported '<!(pymod_do_main module args)' form and expose DoMain in the module.","Inspect the regex match in the GypError's 'contents' to see exactly what GYP parsed as command_string vs. contents, then fix the expression accordingly."],"exampleFix":"// before — 'sh' is not a supported command_string\n'value': '<!(sh gen_version.sh)',\n// after — run the shell script directly\n'value': '<!(sh gen_version.sh)',  # i.e. drop any 'command_string:' prefix the regex mistook; if you had '<!pymod_do_main:...' remove the colon form\n// correct pymod form:\n'value': '<!(pymod_do_main version_helper)',","handlingStrategy":"validation","validationCode":"supported = {'pymod_do_main'}\nassert command_string in supported or command_string == '', \\\n    f'Unsupported GYP command_string {command_string!r}; use pymod_do_main or a plain shell command'","typeGuard":"def is_supported_command_string(cmd: str) -> bool:\n    return cmd in ('', 'pymod_do_main')","tryCatchPattern":null,"preventionTips":["Use only the documented <!() shell form or <!pymod_do_main() — never invent new prefixes.","When copy-pasting expansions from other build systems, strip their prefix syntax first.","Lint .gyp files for 'command_string:' patterns that are not 'pymod_do_main:'."],"tags":["gyp","command-expansion","build-config","syntax"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}