nodejs/node · error · GypError

Action in target %s has no inputs.

Error message

Action in target %s has no inputs.

What it means

Each action must declare an 'inputs' list so the build system knows what files the action depends on. action.get('inputs', None) returning None (key absent) is rejected; an explicit empty list is accepted but pointless.

Source

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

            "The 'environment' for 'run_as' in target %s "
            "in file %s should be a dictionary." % (target_name, build_file)
        )


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)

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Add an 'inputs' key listing the files the action reads.
  2. If the action truly has no inputs, still provide 'inputs': [] (though this usually indicates a design issue).
  3. Re-run gyp.

Example fix

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

Strategy: validation

Validate before calling

for a in target_dict.get('actions', []):
    if 'inputs' not in a:
        raise ValueError(f"action {a.get('action_name')} has no 'inputs' key")

Type guard

def actions_have_inputs(target_dict: dict) -> bool:
    return all('inputs' in a for a in target_dict.get('actions', []))

Prevention

When it happens

Trigger: An action dict in target_dict['actions'] that does not contain an 'inputs' key at all.

Common situations: Authoring an action with only 'outputs' and 'action' and omitting 'inputs'; deleting the inputs line while editing.

Related errors


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