{"record":{"id":"f985b4333aa728cc","repo":"nodejs/node","slug":"the-environment-for-run-as-in-target-s-in-fil","errorCode":null,"errorMessage":"The 'environment' for 'run_as' in target %s in file %s should be a dictionary.","messagePattern":"The 'environment' for 'run_as' in target (.+?) in file (.+?) should be a dictionary\\.","errorType":"exception","errorClass":"GypError","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/gyp/input.py","lineNumber":2799,"sourceCode":"    if not action:\n        raise GypError(\n            \"The 'run_as' in target %s from file %s must have an \"\n            \"'action' section.\" % (target_name, build_file)\n        )\n    if not isinstance(action, list):\n        raise GypError(\n            \"The 'action' for 'run_as' in target %s from file %s \"\n            \"must be a list.\" % (target_name, build_file)\n        )\n    working_directory = run_as.get(\"working_directory\")\n    if working_directory and not isinstance(working_directory, str):\n        raise GypError(\n            \"The 'working_directory' for 'run_as' in target %s \"\n            \"in file %s should be a string.\" % (target_name, build_file)\n        )\n    environment = run_as.get(\"environment\")\n    if environment and not isinstance(environment, dict):\n        raise GypError(\n            \"The 'environment' for 'run_as' in target %s \"\n            \"in file %s should be a dictionary.\" % (target_name, build_file)\n        )\n\n\ndef ValidateActionsInTarget(target, target_dict, build_file):\n    \"\"\"Validates the inputs to the actions in a target.\"\"\"\n    target_name = target_dict.get(\"target_name\")\n    actions = target_dict.get(\"actions\", [])\n    for action in actions:\n        action_name = action.get(\"action_name\")\n        if not action_name:\n            raise GypError(\n                \"Anonymous action in target %s.  \"\n                \"An action must have an 'action_name' field.\" % target_name\n            )\n        inputs = action.get(\"inputs\", None)\n        if inputs is None:","sourceCodeStart":2781,"sourceCodeEnd":2817,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/gyp/input.py#L2781-L2817","documentation":"The optional 'environment' under run_as must be a dict of variable name to value. Other truthy types are rejected because the runner iterates the dict to set subprocess environment variables.","triggerScenarios":"run_as['environment'] is truthy but isinstance(environment, dict) is False.","commonSituations":"Encoding environment as a list of 'K=V' strings or a single string instead of a mapping; misreading the schema from a different build system.","solutions":["Express environment as a dict { 'VAR': 'value' }.","Use string values for each variable.","Re-run gyp."],"exampleFix":"// before\n'run_as': { 'action': ['app'], 'environment': ['FOO=bar', 'BAZ=qux'] },\n// after\n'run_as': { 'action': ['app'], 'environment': { 'FOO': 'bar', 'BAZ': 'qux' } },","handlingStrategy":"type-guard","validationCode":"ra = target_dict.get('run_as')\nif isinstance(ra, dict):\n    env = ra.get('environment')\n    if env and not isinstance(env, dict):\n        raise TypeError('run_as.environment must be a dict')","typeGuard":"def run_as_env_is_dict(target_dict: dict) -> bool:\n    ra = target_dict.get('run_as')\n    if not isinstance(ra, dict):\n        return True\n    env = ra.get('environment')\n    return env is None or isinstance(env, dict)","tryCatchPattern":null,"preventionTips":["Encode environment as {'VAR': 'value'}; never a list of K=V strings.","Keep variable values as strings."],"tags":["gyp","run-as","environment","type","validation"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}