{"record":{"id":"00349c5270b36485","repo":"CherryHQ/cherry-studio","slug":"theme-contract-shadcn-css-cannot-own-runtime-inp","errorCode":null,"errorMessage":"[theme-contract] shadcn.css cannot own runtime input ${declaration.name}","messagePattern":"\\[theme-contract\\] shadcn\\.css cannot own runtime input (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/scripts/validate-theme-contract.ts","lineNumber":274,"sourceCode":"  }\n\n  for (const declaration of extractDeclarations(sources.themeInput, 'theme-input.css')) {\n    if (!runtimeVariables.has(declaration.name)) {\n      throw new Error(`[theme-contract] theme-input.css declares unregistered runtime input ${declaration.name}`)\n    }\n    for (const reference of extractReferences(declaration.value, declaration.source)) {\n      if (officialVariables.has(reference) || productVariables.has(reference) || reference.startsWith('--color-')) {\n        throw new Error(`[theme-contract] runtime input ${declaration.name} cannot depend on upper-layer ${reference}`)\n      }\n      if (reference.startsWith('--app-')) {\n        throw new Error(`[theme-contract] runtime input ${declaration.name} cannot depend on host-local ${reference}`)\n      }\n    }\n  }\n\n  for (const declaration of extractDeclarations(sources.shadcn, 'shadcn.css')) {\n    if (declaration.name.startsWith(runtimeVariablePrefix)) {\n      throw new Error(`[theme-contract] shadcn.css cannot own runtime input ${declaration.name}`)\n    }\n    for (const reference of extractReferences(declaration.value, declaration.source)) {\n      if (productVariables.has(reference) || reference.startsWith('--color-') || reference.startsWith('--app-')) {\n        throw new Error(`[theme-contract] Shadcn ${declaration.name} cannot depend on product/adapter ${reference}`)\n      }\n    }\n  }\n\n  for (const declaration of extractDeclarations(sources.product, 'product.css')) {\n    for (const reference of extractReferences(declaration.value, declaration.source)) {\n      const validNamespace =\n        reference.startsWith('--cs-') || officialVariables.has(reference) || productVariables.has(reference)\n      if (!validNamespace) {\n        throw new Error(`[theme-contract] product ${declaration.name} has invalid dependency ${reference}`)\n      }\n    }\n  }\n}","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/packages/ui/scripts/validate-theme-contract.ts#L256-L292","documentation":"Thrown by assertLayerDependencies when shadcn.css declares a variable whose name starts with the runtime-input prefix --cs-theme-. Runtime inputs are owned exclusively by theme-input.css; shadcn.css must consume them via var(--cs-theme-*), never (re)declare them.","triggerScenarios":"Adding `:root { --cs-theme-primary: hotpink; }` to shadcn.css; pasting a runtime input into shadcn.css while editing.","commonSituations":"Confusing the consumer role (shadcn reads --cs-theme-*) with the owner role; copy-paste from theme-input.css.","solutions":["Remove the --cs-theme-* declaration from shadcn.css.","If the intent was to expose a Shadcn role driven by a runtime input, declare the official Shadcn variable referencing it, e.g. `--primary: var(--cs-theme-primary);`.","If the intent was to define a new runtime input, move it to theme-input.css and register the token."],"exampleFix":"// before (shadcn.css)\n:root { --cs-theme-primary: hotpink; }\n// after — shadcn consumes the runtime input, does not own it\n:root { --primary: var(--cs-theme-primary); }","handlingStrategy":"validation","validationCode":"// shadcn.css must not declare any --cs-theme-* variable.\nconst owned = [...sources.shadcn.matchAll(/(--cs-theme-[a-z0-9-]+)\\s*:/g)].map((m) => m[1])\nif (owned.length) throw new Error(`shadcn.css owns runtime inputs: ${owned.join(', ')}`)","typeGuard":null,"tryCatchPattern":"try {\n  validateThemeContractSources(sources)\n} catch (error) {\n  if (error instanceof Error && /shadcn\\.css cannot own runtime input/.test(error.message)) {\n    console.error(error.message)\n    process.exitCode = 1\n    return\n  }\n  throw error\n}","preventionTips":["shadcn.css consumes runtime inputs via var(--cs-theme-*); it never (re)declares them.","New runtime inputs live in theme-input.css plus RUNTIME_THEME_INPUT_TOKENS.","Run theme:check after editing shadcn.css."],"tags":["theme-contract","css","build","validation","layering"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}