nodejs/node · error · Exception

Unhandled output type %s

Error message

Unhandled output type %s

What it means

Raised as an Exception by the ninja generator's type-specific output path helper when a target's type is not one of the handled kinds (static_library, loadable_module, shared_library, executable, none). There is no fallback output naming rule, so an unknown type cannot produce a build artifact path.

Source

Thrown at tools/gyp/pylib/gyp/generator/ninja.py:1835

            target = spec["product_name"]
        else:
            # Otherwise, derive a name from the target name.
            target = spec["target_name"]
            if prefix == "lib":
                # Snip out an extra 'lib' from libs if appropriate.
                target = StripPrefix(target, "lib")

        if type in (
            "static_library",
            "loadable_module",
            "shared_library",
            "executable",
        ):
            return f"{prefix}{target}{extension}"
        elif type == "none":
            return "%s.stamp" % target
        else:
            raise Exception("Unhandled output type %s" % type)

    def ComputeOutput(self, spec, arch=None):
        """Compute the path for the final output of the spec."""
        type = spec["type"]

        if self.flavor == "win":
            override = self.msvs_settings.GetOutputName(
                self.config_name, self.ExpandSpecial
            )
            if override:
                return override

        if (
            arch is None
            and self.flavor == "mac"
            and type
            in ("static_library", "executable", "shared_library", "loadable_module")
        ):

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Set the target type to a supported value: static_library, loadable_module, shared_library, executable, or none.
  2. Gate targets whose type is non-standard so they are excluded from the ninja build.
  3. Check for typos such as 'static_lib' vs 'static_library'.

Example fix

// before
'targets': [{ 'target_name': 'foo', 'type': 'static_lib' }]
// after
'targets': [{ 'target_name': 'foo', 'type': 'static_library' }]
Defensive patterns

Strategy: validation

Validate before calling

VALID = {'static_library','loadable_module','shared_library','executable','none'}
if spec['type'] not in VALID:
    raise ValueError(f"unhandled output type: {spec['type']}")

Type guard

VALID = {'static_library','loadable_module','shared_library','executable','none'}
def is_handled_ninja_type(spec) -> bool:
    return spec.get('type') in VALID

Prevention

When it happens

Trigger: A target with spec['type'] set to a value outside the handled set reaches the ninja ComputeOutput-by-type code at ninja.py:1831 and falls to the `else` branch. Typically a typo, a custom type, or a type only valid for another generator that leaked into a ninja build.

Common situations: Typo in the type field; a target type introduced for a different build system; conditional type logic that yields an unexpected value under ninja.

Related errors


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