CherryHQ/cherry-studio · error · Error
[theme-contract] shadcn.css declares unregistered Shadcn var
Error message
[theme-contract] shadcn.css declares unregistered Shadcn variable ${declaration.name} What it means
Thrown by validateThemeContractSources when shadcn.css declares a --<name> variable that is not in the SHADCN_VARIABLE_TOKENS registry. The Shadcn contract is a closed set; only registered official variables may be declared there. This catches product roles (e.g. --success) or invented Shadcn roles leaking into shadcn.css.
Source
Thrown at packages/ui/scripts/validate-theme-contract.ts:355
}
assertCompatibilityTokensDeclared(
'compatibility semantic colors',
COMPATIBILITY_SEMANTIC_COLOR_TOKENS,
sources.providerColors,
'tokens/colors/providers.css'
)
assertCompatibilityTokensDeclared(
'compatibility status colors',
COMPATIBILITY_STATUS_COLOR_TOKENS,
sources.statusLegacyColors,
'tokens/colors/status-legacy.css'
)
const shadcnRootDeclarations = buildDeclarationMap([['shadcn.css', sources.shadcn]], ':root')
assertRequiredDeclarations('Shadcn contract in shadcn.css', shadcnRootDeclarations, SHADCN_VARIABLE_TOKENS, '--')
for (const declaration of extractDeclarations(sources.shadcn, 'shadcn.css')) {
if (!shadcnVariableNames.has(declaration.name)) {
throw new Error(`[theme-contract] shadcn.css declares unregistered Shadcn variable ${declaration.name}`)
}
}
const productRootDeclarations = buildDeclarationMap([['product.css', sources.product]], ':root')
assertRequiredDeclarations(
'product contract in product.css',
productRootDeclarations,
CHERRY_PRODUCT_VARIABLE_TOKENS,
'--'
)
assertSurfacePairs('Shadcn contract', SHADCN_SURFACE_PAIRS, shadcnVariables)
assertSurfacePairs('product contract', CHERRY_PRODUCT_SURFACE_PAIRS, productVariables)
assertExactImports('tokens.css', sources.tokensEntry, ['./tokens/index.css'])
assertExactImports('tokens/index.css', sources.tokensIndex, [
'./colors/primitive.css',
'./colors/status-legacy.css',View on GitHub (pinned to 726446b54c)
Solutions
- If it is a genuine new official Shadcn variable, register the unprefixed name in SHADCN_VARIABLE_TOKENS in scripts/theme-contract.ts, declare it in shadcn.css :root, and document it in variable-catalog.md.
- If it is a product role (e.g. --success), move the declaration to product.css and ensure it is in CHERRY_PRODUCT_VARIABLE_TOKENS.
- Re-run `pnpm --filter @cherrystudio/ui theme:check`.
Example fix
// before (shadcn.css)
:root { --success: hotpink; }
// after — move to product.css (success is a product token)
// product.css
:root { --success: var(--cs-green-600); } Defensive patterns
Strategy: validation
Validate before calling
// Every variable declared in shadcn.css must be a registered Shadcn variable.
const allowed = new Set(SHADCN_VARIABLE_TOKENS.map((t) => `--${t}`))
const offenders = [...sources.shadcn.matchAll(/(?:^|[;{])\s*(--[a-z0-9-]+)\s*:/g)].map((m) => m[1]).filter((n) => !allowed.has(n))
if (offenders.length) throw new Error(`shadcn.css declares unregistered vars: ${offenders.join(', ')}`) Try / catch
try {
validateThemeContractSources(sources)
} catch (error) {
if (error instanceof Error && /shadcn\.css declares unregistered Shadcn variable/.test(error.message)) {
console.error(error.message)
process.exitCode = 1
return
}
throw error
} Prevention
- Only official SHADCN_VARIABLE_TOKENS may be declared in shadcn.css.
- Product roles (--success, --link, ...) belong in product.css, not shadcn.css.
- When extending the Shadcn surface, update the registry, the CSS, and the catalog together.
When it happens
Trigger: Adding `:root { --success: hotpink; }` to shadcn.css (success is a product variable); inventing a new official role `--new-role` without registering it; pasting a product declaration into shadcn.css.
Common situations: Adding a Shadcn component's variable to the wrong file; extending the Shadcn surface and forgetting the registry.
Related errors
- [theme-contract] theme-input.css declares unregistered runti
- [theme-contract] product variable ${token} overlaps the offi
- [theme-contract] Tailwind product color ${token} is missing
- [theme-contract] compatibility color ${token} overlaps the c
- [theme-contract] product.css declares unregistered product v
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/aa9c8d2966f0c73b.
Report an issue: GitHub.