nodejs/node · error · GypError

Empty action as command in target %s.

Error message

Empty action as command in target %s.

What it means

ValidateActionsInTarget checks that, when an 'action' command list is present, its first element (the executable) is non-empty. An empty program name would produce an unrunnable build step, so it is rejected up front.

Source

Thrown at tools/gyp/pylib/gyp/input.py:2821


def ValidateActionsInTarget(target, target_dict, build_file):
    """Validates the inputs to the actions in a target."""
    target_name = target_dict.get("target_name")
    actions = target_dict.get("actions", [])
    for action in actions:
        action_name = action.get("action_name")
        if not action_name:
            raise GypError(
                "Anonymous action in target %s.  "
                "An action must have an 'action_name' field." % target_name
            )
        inputs = action.get("inputs", None)
        if inputs is None:
            raise GypError("Action in target %s has no inputs." % target_name)
        action_command = action.get("action")
        if action_command and not action_command[0]:
            raise GypError("Empty action as command in target %s." % target_name)


def TurnIntIntoStrInDict(the_dict):
    """Given dict the_dict, recursively converts all integers into strings."""
    # Use items instead of iteritems because there's no need to try to look at
    # reinserted keys and their associated values.
    for k, v in the_dict.items():
        if isinstance(v, int):
            v = str(v)
            the_dict[k] = v
        elif isinstance(v, dict):
            TurnIntIntoStrInDict(v)
        elif isinstance(v, list):
            TurnIntIntoStrInList(v)

        if isinstance(k, int):
            del the_dict[k]
            the_dict[str(k)] = v

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Inspect the first element of the action command list and ensure it is the real executable path or command.
  2. Fix any variable expansion that produced an empty string.
  3. Re-run gyp.

Example fix

// before
{ 'action_name': 'gen', 'inputs': ['in'], 'action': ['', 'out.cc'] },
// after
{ 'action_name': 'gen', 'inputs': ['in'], 'action': ['gen', 'out.cc'] },
Defensive patterns

Strategy: validation

Validate before calling

for a in target_dict.get('actions', []):
    cmd = a.get('action')
    if cmd and not cmd[0]:
        raise ValueError(f"action {a.get('action_name')} has an empty command")

Type guard

def actions_have_nonempty_command(target_dict: dict) -> bool:
    for a in target_dict.get('actions', []):
        cmd = a.get('action')
        if cmd and not cmd[0]:
            return False
    return True

Prevention

When it happens

Trigger: action.get('action') is truthy (a non-empty list) but the first element action['action'][0] is falsy, typically an empty string.

Common situations: A variable expansion that resolved to an empty program name; an action list that starts with '' by mistake; malformed argv after editing.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/4aca1a80e8d727ea. Report an issue: GitHub.