nodejs/node · error · GypError

The 'working_directory' for 'run_as' in target %s in file %s

Error message

The 'working_directory' for 'run_as' in target %s in file %s should be a string.

What it means

The optional 'working_directory' under run_as must be a string path. Any other truthy type is rejected before it is handed to the build tooling that changes into that directory before running the action.

Source

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

    if not isinstance(run_as, dict):
        raise GypError(
            "The 'run_as' in target %s from file %s should be a "
            "dictionary." % (target_name, build_file)
        )
    action = run_as.get("action")
    if not action:
        raise GypError(
            "The 'run_as' in target %s from file %s must have an "
            "'action' section." % (target_name, build_file)
        )
    if not isinstance(action, list):
        raise GypError(
            "The 'action' for 'run_as' in target %s from file %s "
            "must be a list." % (target_name, build_file)
        )
    working_directory = run_as.get("working_directory")
    if working_directory and not isinstance(working_directory, str):
        raise GypError(
            "The 'working_directory' for 'run_as' in target %s "
            "in file %s should be a string." % (target_name, build_file)
        )
    environment = run_as.get("environment")
    if environment and not isinstance(environment, dict):
        raise GypError(
            "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:

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Make working_directory a single string path (typically a gyp variable expansion like '<(PRODUCT_DIR)').
  2. If a list expansion caused it, fix the variable so it yields one path string.
  3. Re-run gyp.

Example fix

// before
'run_as': { 'action': ['app'], 'working_directory': ['<(PRODUCT_DIR)'] },
// after
'run_as': { 'action': ['app'], 'working_directory': '<(PRODUCT_DIR)' },
Defensive patterns

Strategy: type-guard

Validate before calling

ra = target_dict.get('run_as')
if isinstance(ra, dict):
    wd = ra.get('working_directory')
    if wd and not isinstance(wd, str):
        raise TypeError('run_as.working_directory must be a string')

Type guard

def run_as_wd_is_str(target_dict: dict) -> bool:
    ra = target_dict.get('run_as')
    if not isinstance(ra, dict):
        return True
    wd = ra.get('working_directory')
    return wd is None or isinstance(wd, str)

Prevention

When it happens

Trigger: run_as['working_directory'] is truthy but isinstance(working_directory, str) is False.

Common situations: Setting working_directory to a list (e.g. a gyp list expansion that produced multiple values) or to a dict; a variable expansion that resolved to a non-string object.

Related errors


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