evanw/esbuild · critical

Invalid color

Error message

Invalid color

What it means

validateColor (pkg/api/api_impl.go:185) panics when StderrColor is not ColorIfTerminal(0), ColorNever(1), or ColorAlways(2). The return value drives logger.UseColor which controls ANSI escape emission in diagnostic output; an unknown value would produce undefined terminal behavior, so esbuild aborts. Called early in contextImpl and Transform option processing.

Solutions

  1. Use api.ColorIfTerminal (default, leave field unset) or api.ColorNever / api.ColorAlways.
  2. Bounds-check any externally supplied integer against 0..2 before casting.
  3. Persist the preference as a string ("auto"/"never"/"always") and map it to the constant at load time.
  4. Re-vendor and rebuild bridges against the same esbuild version.

Example fix

// before
opts := api.BuildOptions{Color: api.StderrColor(7)}

// after
opts := api.BuildOptions{Color: api.ColorIfTerminal}
Defensive patterns

Strategy: validation

Validate before calling

func checkColor(c api.StderrColor) error {
    switch c {
    case api.ColorIfTerminal, api.ColorNever, api.ColorAlways:
        return nil
    }
    return fmt.Errorf("invalid color %d (want 0..2)", uint8(c))
}

Type guard

func isValidColor(c api.StderrColor) bool {
    switch c {
    case api.ColorIfTerminal, api.ColorNever, api.ColorAlways:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Assigning Color from a raw integer, an int8/uint8 deserialization, or a bridge that maps a different numbering. The panic occurs while building logger.OutputOptions, before any source file is parsed.

Common situations: CLI/JS shims that pass `--color` numeric flags to the Go core with mismatched ordinals, persisted user-preference files that store Color as a number, or tests that hand-craft BuildOptions with `Color: api.StderrColor(9)`.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/8105158bb42bd58a. Report an issue: GitHub.

Appendix: source

Thrown at pkg/api/api_impl.go:185

	case LegalCommentsLinked:
		return config.LegalCommentsLinkedWithComment
	case LegalCommentsExternal:
		return config.LegalCommentsExternalWithoutComment
	default:
		panic("Invalid legal comments")
	}
}

func validateColor(value StderrColor) logger.UseColor {
	switch value {
	case ColorIfTerminal:
		return logger.ColorIfTerminal
	case ColorNever:
		return logger.ColorNever
	case ColorAlways:
		return logger.ColorAlways
	default:
		panic("Invalid color")
	}
}

func validateLogLevel(value LogLevel) logger.LogLevel {
	switch value {
	case LogLevelVerbose:
		return logger.LevelVerbose
	case LogLevelDebug:
		return logger.LevelDebug
	case LogLevelInfo:
		return logger.LevelInfo
	case LogLevelWarning:
		return logger.LevelWarning
	case LogLevelError:
		return logger.LevelError
	case LogLevelSilent:
		return logger.LevelSilent
	default:

View on GitHub (pinned to f6058f8364)