{"record":{"id":"3828bae4a31b9ff4","repo":"CherryHQ/cherry-studio","slug":"theme-contract-runtime-input-declaration-name","errorCode":null,"errorMessage":"[theme-contract] runtime input ${declaration.name} cannot depend on upper-layer ${reference}","messagePattern":"\\[theme-contract\\] runtime input (.+?) cannot depend on upper-layer (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/scripts/validate-theme-contract.ts","lineNumber":264,"sourceCode":"          reference.startsWith(runtimeVariablePrefix) ||\n          officialVariables.has(reference) ||\n          productVariables.has(reference) ||\n          reference.startsWith('--color-') ||\n          reference.startsWith('--app-')\n        ) {\n          throw new Error(`[theme-contract] foundation ${declaration.name} cannot depend on upper-layer ${reference}`)\n        }\n      }\n    }\n  }\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","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/packages/ui/scripts/validate-theme-contract.ts#L246-L282","documentation":"Thrown by assertLayerDependencies when a runtime-input declaration (--cs-theme-*) in theme-input.css references an upper-layer variable: an official Shadcn variable, a product variable, or a Tailwind adapter variable (--color-*). Runtime inputs sit between foundation and Shadcn; they translate foundation values for the host and must only depend on foundation or other runtime inputs.","triggerScenarios":"Replacing `var(--cs-primary)` with `var(--primary)` in theme-input.css; setting `--cs-theme-primary: var(--success);` (product dep); `--cs-theme-primary: var(--color-blue-500);` (adapter dep).","commonSituations":"Trying to make a runtime input follow a Shadcn/product role instead of a foundation primitive; copy-pasting a value reference from the wrong layer.","solutions":["Re-point the runtime input at a foundation-layer variable (--cs-* or a primitive).","If the dependency on an upper layer is intentional, the relationship is inverted: move the logic so the upper layer references the runtime input (e.g. shadcn.css `--primary: var(--cs-theme-primary)`), not the reverse.","Re-run `pnpm --filter @cherrystudio/ui theme:check`."],"exampleFix":"// before (theme-input.css)\n--cs-theme-primary: var(--primary);\n// after — runtime input depends only on foundation\n--cs-theme-primary: var(--cs-primary);","handlingStrategy":"validation","validationCode":"// Runtime inputs must not reference shadcn/product/adapter variables.\nconst upperLayer = (ref: string) => ref.startsWith('--color-') || SHADCN_VARIABLE_TOKENS.includes(ref.slice(2) as never) || CHERRY_PRODUCT_VARIABLE_TOKENS.includes(ref.slice(2) as never)\nfor (const [, ref] of sources.themeInput.matchAll(/var\\(\\s*(--[a-z0-9-]+)/g)) {\n  if (upperLayer(ref)) throw new Error(`runtime input depends on upper layer ${ref}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  validateThemeContractSources(sources)\n} catch (error) {\n  if (error instanceof Error && /runtime input .* cannot depend on upper-layer/.test(error.message)) {\n    console.error(error.message)\n    process.exitCode = 1\n    return\n  }\n  throw error\n}","preventionTips":["Runtime inputs translate foundation values for the host; point them only at --cs-* or other runtime inputs.","If a runtime input should follow a Shadcn/product role, the dependency direction is inverted: shadcn/product reference the runtime input.","Run theme:check after editing theme-input.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"}