tailwindlabs/tailwindcss · error · Error

Could not find the Tailwind CSS v3 `prefix` configuration in

Error message

Could not find the Tailwind CSS v3 `prefix` configuration inside the JavaScript config.

What it means

`extractV3Base` parses a v3 candidate with prefix awareness. It first checks `designSystem.theme.prefix`; if a prefix is configured in the design system, it then requires the v3 JS config to also declare `userConfig.prefix`. If the config omits `prefix` while the design system has one, the migration cannot align the two prefix sources and throws.

Source

Thrown at packages/@tailwindcss-upgrade/src/codemods/template/migrate-prefix.ts:74

    designSystem.theme.prefix = originalPrefix
  }

  if (!candidate) return rawCandidate

  return designSystem.printCandidate(candidate)
}

// Parses a raw candidate with v3 compatible prefix syntax. This won't match if
// the `base` part of the candidate does not match the configured prefix, unless
// a bare candidate is used.
function extractV3Base(
  designSystem: DesignSystem,
  userConfig: Config,
  rawCandidate: string,
): { base: string; start: number; end: number } | null {
  if (!designSystem.theme.prefix) return null
  if (!userConfig.prefix)
    throw new Error(
      'Could not find the Tailwind CSS v3 `prefix` configuration inside the JavaScript config.',
    )

  // hover:focus:underline
  // ^^^^^ ^^^^^^           -> Variants
  //             ^^^^^^^^^  -> Base
  let rawVariants = segment(rawCandidate, ':')

  // SAFETY: At this point it is safe to use TypeScript's non-null assertion
  // operator because even if the `input` was an empty string, splitting an
  // empty string by `:` will always result in an array with at least one
  // element.
  let base = rawVariants.pop()!
  let start = rawCandidate.length - base.length
  let end = start + base.length

  let important = false
  let negative = false

View on GitHub (pinned to 16e94cbf7f)

Solutions

  1. Add the matching `prefix` field to the v3 JS config (e.g. `prefix: 'tw-'`) so it agrees with the design system's `@theme` prefix.
  2. Or remove the prefix from `@theme` if no prefix is intended, then re-run the upgrade.
  3. Ensure the prefix values are identical across both sources.

Example fix

// before (config missing prefix while @theme has one)
module.exports = { theme: { /* … */ } }

// after
module.exports = { prefix: 'tw-', theme: { /* … */ } }
Defensive patterns

Strategy: validation

Validate before calling

function assertPrefixConsistency(designSystemPrefix: string | undefined, userConfigPrefix: string | undefined) {
  if (designSystemPrefix && !userConfigPrefix) {
    throw new Error('Design system has a prefix but the JS config omits prefix; add matching prefix:')
  }
}

Prevention

When it happens

Trigger: Running the upgrade with a design system built from a CSS `@theme` that defines a prefix, but the legacy `tailwind.config.js` has no `prefix` field (or it was deleted). migrate-prefix.ts:74 throws after the `designSystem.theme.prefix` truthiness check passes but `userConfig.prefix` is falsy.

Common situations: Partially migrated configs where the prefix was moved into `@theme` but the JS config was stripped, or inconsistent prefix configuration between CSS and JS during a manual migration attempt.

Related errors


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