shadcn-ui/ui · warning
Skipped ${skippedTokens.size} token${skippedTokens.size ===
Error message
Skipped ${skippedTokens.size} token${skippedTokens.size === 1 ? "" : "s"}. These were left untouched: What it means
Not a thrown exception — a logger.warn emitted after the base-color migration finishes. getBaseColorMigration only rewrites tokens that currently still hold the source palette's stock value; tokens missing from your CSS ('not found in your CSS') or manually customized ('does not match the source base color') are collected and reported here, left untouched on purpose so your overrides survive.
Source
Thrown at packages/shadcn/src/migrations/migrate-base-color.ts:186
})
}
migrationSpinner.succeed("Migration complete.")
// Keep components.json in sync so future `shadcn add` installs use the new
// base color.
await updateConfigBaseColor(config, targetBaseColor)
const skippedTokens = new Map<string, string>()
for (const { token, reason } of skipped) {
if (!skippedTokens.has(token)) {
skippedTokens.set(token, reason)
}
}
if (skippedTokens.size > 0) {
logger.break()
logger.warn(
`Skipped ${skippedTokens.size} token${
skippedTokens.size === 1 ? "" : "s"
}. These were left untouched:`
)
for (const [token, reason] of Array.from(skippedTokens)) {
logger.warn(` - ${token}: ${reason}`)
}
}
}
export function getBaseColorMigration(
css: string,
sourceVars: CssVars,
targetVars: CssVars,
tailwindVersion: TailwindVersion
): {
cssVars: { light: Record<string, string>; dark: Record<string, string> }
skipped: SkippedToken[]View on GitHub (pinned to c06da1d0e9)
Solutions
- Treat the warning as a review list: open your CSS and update each listed token to the target palette's value (or confirm you want to keep the override).
- If a listed token should have migrated, reset it to the source palette's stock value in your CSS and re-run `shadcn migrate base-color` — it will then match and be replaced.
- Fetch the target palette values from the registry (colors/<to>.json) to copy exact values for manual updates.
Example fix
/* before — hand-tuned token blocked the swap; migration warned:
Skipped 1 token. These were left untouched:
- --primary: does not match the source base color */
:root { --primary: 142 76% 36%; }
/* after — manually port the token to the target palette (neutral) */
:root { --primary: 0 0% 9%; } Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from 'fs'
import postcss from 'postcss'
// Dry-run the migration's own matcher before writing anything:
// tokens absent from :root/.dark or diverging from the stock source values will be skipped.
function findAtRiskTokens(cssPath: string, stockSourceVars: Record<string, string>): string[] {
const current: Record<string, string> = {}
postcss.parse(readFileSync(cssPath, 'utf-8')).walkRules((rule) => {
if (rule.selector !== ':root' && rule.selector !== '.dark') return
rule.walkDecls((d) => { if (d.prop.startsWith('--')) current[d.prop] = d.value.trim().replace(/\s+/g, ' ') })
})
return Object.entries(stockSourceVars)
.filter(([name, value]) => current[`--${name}`] !== value.trim().replace(/\s+/g, ' '))
.map(([name]) => `--${name}`)
} Prevention
- Keep theme tokens at stock palette values in source control; apply brand overrides after (or in separate tokens) so migrations can match them.
- Run `getBaseColorMigration(css, sourceVars, targetVars, tailwindVersion)` as a dry-run (it is exported) and review the returned `skipped` list before letting the CLI write.
- Expect the warning on customized themes — it protects your overrides rather than indicating failure.
When it happens
Trigger: Running `shadcn migrate base-color` on a stylesheet where some source-palette tokens are absent (partial :root/.dark blocks) or hold hand-edited values — e.g. you tweaked --primary or --radius yourself — plus tokens identical in both palettes are silently skipped without being listed.
Common situations: Hand-tuned themes; Tailwind v3 to v4 transitions where values are written differently (hsl() wrapping); partially adopted variable sets; brand color overrides that developers actually want preserved.
Related errors
- - ${token}: ${reason}
- The `base-color` migration requires CSS variables. Your `com
- You cannot migrate to the same base color. Please choose a d
- We could not find a valid CSS file in your `components.json`
- Unknown base color: ${options.to}. Available base colors: ${
AI-assisted analysis of shadcn-ui/ui@c06da1d0e9 (2026-08-21).
Data as JSON: /api/errors/d05c95345a3becff.
Report an issue: GitHub.