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 = falseView on GitHub (pinned to 16e94cbf7f)
Solutions
- Add the matching `prefix` field to the v3 JS config (e.g. `prefix: 'tw-'`) so it agrees with the design system's `@theme` prefix.
- Or remove the prefix from `@theme` if no prefix is intended, then re-run the upgrade.
- 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
- Keep prefix declarations identical in @theme and the JS config during migration.
- Don't strip the JS config prefix while a @theme prefix remains.
- Re-run the upgrade after aligning both prefix sources.
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
- Unsupported content value: ${pattern}
- You have one or more stylesheets that are imported into a ut
- Cannot find any CSS files that reference Tailwind CSS. Befor
- No configuration file found for ${highlight(relative(start))
- Tailwind CSS is not installed
AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12).
Data as JSON: /api/errors/f917a35b0f323e25.
Report an issue: GitHub.