CherryHQ/cherry-studio · error · Error
[theme-contract] Shadcn ${declaration.name} cannot depend on
Error message
[theme-contract] Shadcn ${declaration.name} cannot depend on product/adapter ${reference} What it means
Thrown by assertLayerDependencies when a declaration in shadcn.css references a product variable (--success, --link, etc.), a Tailwind adapter variable (--color-*), or a host-local variable (--app-*). Shadcn is the official upstream contract layer and must only depend on foundation and runtime inputs; referencing product/adapter/host concerns would couple the upstream contract to Cherry-specific or host-specific layers.
Source
Thrown at packages/ui/scripts/validate-theme-contract.ts:278
throw new Error(`[theme-contract] theme-input.css declares unregistered runtime input ${declaration.name}`)
}
for (const reference of extractReferences(declaration.value, declaration.source)) {
if (officialVariables.has(reference) || productVariables.has(reference) || reference.startsWith('--color-')) {
throw new Error(`[theme-contract] runtime input ${declaration.name} cannot depend on upper-layer ${reference}`)
}
if (reference.startsWith('--app-')) {
throw new Error(`[theme-contract] runtime input ${declaration.name} cannot depend on host-local ${reference}`)
}
}
}
for (const declaration of extractDeclarations(sources.shadcn, 'shadcn.css')) {
if (declaration.name.startsWith(runtimeVariablePrefix)) {
throw new Error(`[theme-contract] shadcn.css cannot own runtime input ${declaration.name}`)
}
for (const reference of extractReferences(declaration.value, declaration.source)) {
if (productVariables.has(reference) || reference.startsWith('--color-') || reference.startsWith('--app-')) {
throw new Error(`[theme-contract] Shadcn ${declaration.name} cannot depend on product/adapter ${reference}`)
}
}
}
for (const declaration of extractDeclarations(sources.product, 'product.css')) {
for (const reference of extractReferences(declaration.value, declaration.source)) {
const validNamespace =
reference.startsWith('--cs-') || officialVariables.has(reference) || productVariables.has(reference)
if (!validNamespace) {
throw new Error(`[theme-contract] product ${declaration.name} has invalid dependency ${reference}`)
}
}
}
}
function assertCatalogCoverage(sources: ThemeContractSources): void {
const requiredNames = [
...RUNTIME_THEME_INPUT_TOKENS.map((token) => `--cs-theme-${token}`),View on GitHub (pinned to 726446b54c)
Solutions
- Re-point the Shadcn variable at a foundation variable (--cs-*) or a runtime input (--cs-theme-*).
- If the dependency on a product/adapter variable is intentional, invert it: declare the value in product.css and have product.css reference the Shadcn variable (product layer may reference shadcn, not the reverse).
- Re-run `pnpm --filter @cherrystudio/ui theme:check`.
Example fix
// before (shadcn.css) --background: var(--success); // after — shadcn references foundation only --background: var(--cs-background);
Defensive patterns
Strategy: validation
Validate before calling
// shadcn.css must not reference product/adapter/host variables.
const productNames = new Set(CHERRY_PRODUCT_VARIABLE_TOKENS.map((t) => `--${t}`))
for (const [, ref] of sources.shadcn.matchAll(/var\(\s*(--[a-z0-9-]+)/g)) {
if (productNames.has(ref) || ref.startsWith('--color-') || ref.startsWith('--app-')) {
throw new Error(`shadcn depends on product/adapter/host ${ref}`)
}
} Try / catch
try {
validateThemeContractSources(sources)
} catch (error) {
if (error instanceof Error && /Shadcn .* cannot depend on product\/adapter/.test(error.message)) {
console.error(error.message)
process.exitCode = 1
return
}
throw error
} Prevention
- shadcn.css is the upstream contract: only foundation and runtime inputs.
- To reuse a product value, invert the dependency in product.css (product may reference shadcn).
- Run theme:check after editing shadcn.css.
When it happens
Trigger: Adding `--background: var(--success);` to shadcn.css (product dep); `--primary: var(--color-blue-500);` (adapter dep); `--background: var(--app-surface);` (host-local dep).
Common situations: Trying to reuse a product role inside the official contract; pulling a Tailwind utility color into a Shadcn variable.
Related errors
- [theme-contract] foundation cannot declare runtime input ${d
- [theme-contract] foundation ${declaration.name} cannot depen
- [theme-contract] runtime input ${declaration.name} cannot de
- [theme-contract] runtime input ${declaration.name} cannot de
- [theme-contract] shadcn.css cannot own runtime input ${decla
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/196dd28925a58eda.
Report an issue: GitHub.