tailwindlabs/tailwindcss · error · Error

Invalid theme value `${value}` for namespace `${key}`

Error message

Invalid theme value `${value}` for namespace `${key}`

What it means

Thrown by Theme.add() when a namespace-clearing key (one ending in '-*', e.g. '--color-*' or '--*') is paired with a value other than the literal string 'initial'. In Tailwind v4's @theme block, a trailing '-*' declares intent to clear an entire namespace, and 'initial' is the only legal value for that operation. Any other value is treated as a malformed clear directive.

Source

Thrown at packages/tailwindcss/src/theme.ts:63

    private values = new Map<
      string,
      {
        value: string
        options: ThemeOptions
        src: Declaration['src']
      }
    >(),
    private keyframes = new Set<AtRule>([]),
  ) {}

  get size() {
    return this.values.size
  }

  add(key: string, value: string, options = ThemeOptions.NONE, src?: Declaration['src']): void {
    if (key.endsWith('-*')) {
      if (value !== 'initial') {
        throw new Error(`Invalid theme value \`${value}\` for namespace \`${key}\``)
      }
      if (key === '--*') {
        this.values.clear()
      } else {
        this.clearNamespace(
          key.slice(0, -2),
          // `--${key}-*: initial;` should clear _all_ theme values
          ThemeOptions.NONE,
        )
      }
    }

    if (options & ThemeOptions.DEFAULT) {
      let existing = this.values.get(key)
      if (existing && !(existing.options & ThemeOptions.DEFAULT)) return
    }

    if (value === 'initial') {

View on GitHub (pinned to 16e94cbf7f)

Solutions

  1. If you intend to clear the namespace, use the literal value 'initial': `--color-*: initial;`
  2. If you intend to set specific values, list each key explicitly: `--color-red-500: #f87171;` instead of using the '-*' wildcard.
  3. If you want to replace every color, clear with '--color-*: initial;' first, then declare the new individual values below it.

Example fix

/* before — throws */
@theme {
  --color-*: #f00;
}

/* after — clears, then sets */
@theme {
  --color-*: initial;
  --color-primary: #f00;
}
Defensive patterns

Strategy: validation

Validate before calling

// Before calling theme.add with a namespace key
function isNamespaceClear(key: string, value: string): boolean {
  return key.endsWith('-*') && value !== 'initial'
}
if (isNamespaceClear(key, value)) {
  throw new Error(`Namespace key '${key}' requires value 'initial', got '${value}'`)
}
theme.add(key, value)

Type guard

function isLegalNamespaceValue(key: string, value: string): boolean {
  return !key.endsWith('-*') || value === 'initial'
}

Prevention

When it happens

Trigger: Writing CSS like `@theme { --color-*: red; }` (clearing syntax with a non-initial value), or programmatically calling theme.add('--color-*', 'blue'). Also fires for `--*` (the global clear) with any value besides 'initial'. The check at theme.ts:62 runs before the namespace is actually cleared, so the theme map is left untouched.

Common situations: Mistaking the namespace-clear syntax for a wildcard setter (expecting '--color-*: red' to set every color to red). Copying a CSS reset pattern from elsewhere. Upgrading from v3 where theme keys behaved differently and assuming '-*' is a glob assignment.

Related errors


AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12). Data as JSON: /api/errors/1f23b4d336a3712e. Report an issue: GitHub.