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

  1. Re-point the Shadcn variable at a foundation variable (--cs-*) or a runtime input (--cs-theme-*).
  2. 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).
  3. 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

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


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/196dd28925a58eda. Report an issue: GitHub.