shadcn-ui/ui · error · Error
The `base-color` migration requires CSS variables. Your `com
Error message
The `base-color` migration requires CSS variables. Your `components.json` has `cssVariables: false`, which uses inline Tailwind color classes instead of theme variables.
What it means
Second guard inside migrateBaseColor. The base-color migration works by swapping theme CSS variables (--background, --primary, ...) between palettes; it cannot operate on projects configured with `tailwind.cssVariables: false`, which use inline Tailwind color classes (bg-neutral-900, text-zinc-500) instead of variables. The guard rejects that configuration up front instead of silently doing nothing.
Source
Thrown at packages/shadcn/src/migrations/migrate-base-color.ts:45
reason: string
}
export async function migrateBaseColor(
config: Config,
options: {
from?: string
to?: string
yes?: boolean
} = {}
) {
if (!config.resolvedPaths.tailwindCss) {
throw new Error(
"We could not find a valid CSS file in your `components.json` file. Please ensure you have a valid `tailwind.css` path in your `components.json` file."
)
}
if (!config.tailwind.cssVariables) {
throw new Error(
"The `base-color` migration requires CSS variables. Your `components.json` has `cssVariables: false`, which uses inline Tailwind color classes instead of theme variables."
)
}
const baseColorChoices = BASE_COLORS.map((baseColor) => ({
title: baseColor.label,
value: baseColor.name,
}))
const baseColorNames: string[] = BASE_COLORS.map(
(baseColor) => baseColor.name
)
// Only the target is validated. The source can be a legacy base color
// (e.g. slate) an existing project still uses.
if (options.to && !baseColorNames.includes(options.to)) {
throw new Error(
`Unknown base color: ${options.to}. Available base colors: ${baseColorNames.join(
", "View on GitHub (pinned to c06da1d0e9)
Solutions
- Adopt CSS variables first: set "cssVariables": true in components.json and convert your components/classes to use theme variables (re-running `shadcn init` with css variables, or updating the theme stylesheet to define :root/.dark vars), then re-run the base-color migration.
- If you intend to keep inline color classes, skip this migration entirely — change colors by swapping the Tailwind palette in your Tailwind config/classes manually.
Example fix
// before — components.json
"tailwind": { "css": "~/src/app/globals.css", "baseColor": "zinc", "cssVariables": false }
// after (after also converting classes/defs to theme variables)
"tailwind": { "css": "~/src/app/globals.css", "baseColor": "zinc", "cssVariables": true } Defensive patterns
Strategy: validation
Validate before calling
// Before running `shadcn migrate base-color`, read components.json and check the flag:
import { readFileSync } from 'fs'
const config = JSON.parse(readFileSync('components.json', 'utf-8'))
if (config.tailwind?.cssVariables !== true) {
console.error(
'base-color migration needs cssVariables: true. Convert the project to theme variables first.'
)
process.exit(1)
} Type guard
type RawConfig = { tailwind?: { cssVariables?: boolean } }
function usesCssVariables(raw: unknown): raw is RawConfig & {
tailwind: { cssVariables: true }
} {
return (
!!raw &&
typeof raw === 'object' &&
(raw as RawConfig).tailwind?.cssVariables === true
)
} Prevention
- Initialize new projects with CSS variables enabled (the default) so base-color migrations remain available.
- Treat `cssVariables: false` as a deliberate lock-out of theme migrations; record it in the project README.
- When inheriting an old project, check this flag before attempting any shadcn migration.
When it happens
Trigger: Running `npx shadcn@latest migrate base-color` on a project whose components.json contains "cssVariables": false — typically projects initialized with --no-css-vars or created by older shadcn versions that defaulted to inline classes.
Common situations: Legacy shadcn/Tailwind v3 projects that never adopted CSS variables; teams that deliberately chose inline palette classes; copying a components.json from an old project into a new one.
Related errors
- Invalid input: not an object literal
- We could not find a valid CSS file in your `components.json`
- Skipped ${skippedTokens.size} token${skippedTokens.size ===
- - ${token}: ${reason}
- Failed to read config at ${options.cwd}.
AI-assisted analysis of shadcn-ui/ui@c06da1d0e9 (2026-08-21).
Data as JSON: /api/errors/acae61dbf4ac7dc2.
Report an issue: GitHub.