CherryHQ/cherry-studio · error · Error
[theme-contract] renderer TypeScript source ${fileName} cann
Error message
[theme-contract] renderer TypeScript source ${fileName} cannot use Tailwind adapter variable ${adapterVariable}; use runtime semantic variables or Tailwind utilities What it means
Thrown by the theme migration contract validator when a renderer TypeScript source file (.ts/.tsx under src/renderer/) contains a string literal, template literal, or JSX text referencing a Tailwind adapter variable (--color-*). Unlike the CSS check (error 30), this scans TypeScript AST nodes (StringLiteral, NoSubstitutionTemplateLiteral, TemplateExpression spans, JsxText) for adapter variable patterns. The contract requires TS code to use runtime semantic variables or Tailwind utility classes.
Source
Thrown at packages/ui/scripts/validate-migration-contract.ts:204
if (/@theme(?:\s+inline)?\s*\{/.test(rendererTheme)) {
throw new Error('[theme-contract] renderer theme must use the shared generated Tailwind adapter')
}
for (const [fileName, source] of Object.entries(sources.rendererStyles)) {
const adapterVariable = stripComments(source).match(TAILWIND_ADAPTER_VARIABLE_PATTERN)?.[0]
if (adapterVariable) {
throw new Error(
`[theme-contract] renderer stylesheet ${fileName} cannot use Tailwind adapter variable ${adapterVariable}; use runtime semantic variables directly`
)
}
}
for (const [fileName, source] of Object.entries(sources.rendererTypeScriptSources)) {
const adapterVariable = source.includes('--color-') ? findTypeScriptAdapterVariable(source, fileName) : undefined
if (adapterVariable) {
throw new Error(
`[theme-contract] renderer TypeScript source ${fileName} cannot use Tailwind adapter variable ${adapterVariable}; use runtime semantic variables or Tailwind utilities`
)
}
const disallowedWrite = findTypeScriptDisallowedThemeWrite(source, fileName)
if (disallowedWrite) {
throw new Error(
`[theme-contract] renderer TypeScript source ${fileName} cannot write shared theme variable ${disallowedWrite}; use a registered --cs-theme-* input or an owner-local --app-* variable`
)
}
}
}
export async function loadMigrationContractSources(
repositoryRoot = DEFAULT_REPOSITORY_ROOT
): Promise<MigrationContractSources> {
const [migrationRegistry, legacyAliases, rendererTheme, rendererStyleEntries, rendererTypeScriptEntries] =
await Promise.all([View on GitHub (pinned to 726446b54c)
Solutions
- Replace the --color-* reference in the TS string with the semantic variable name (e.g., '--color-primary-500' → '--primary').
- If applying the color via inline styles, use the semantic CSS variable: style={{ color: 'var(--primary)' }}.
- If the value should be a Tailwind utility class, use the className instead (e.g., className="text-primary").
- Confirm the fix by running: npx tsx packages/ui/scripts/validate-migration-contract.ts.
Example fix
// before — renderer .tsx file
<div style={{ background: 'var(--color-blue-500)' }}>...</div>
// after — use semantic variable or Tailwind class
<div style={{ background: 'var(--primary)' }}>...</div>
// or
<div className="bg-primary">...</div> Defensive patterns
Strategy: validation
Validate before calling
// Scan renderer .ts/.tsx files for --color-* adapter variable strings before committing
import { readFileSync } from 'node:fs'
function checkNoAdapterVarsInTs(tsPath: string): void {
const source = readFileSync(tsPath, 'utf8')
if (source.includes('--color-')) {
const match = source.match(/--color-[a-z0-9-]*/)
if (match) {
throw new Error(`${tsPath} references adapter variable ${match[0]} in a string — use semantic variables or Tailwind classes`)
}
}
} Prevention
- Use semantic CSS variables (var(--primary)) or Tailwind utility classes (text-primary) in TypeScript inline styles — never raw --color-* tokens.
- When using setProperty or inline styles in components, reference the semantic variable names.
- Run the migration contract validator in CI to catch adapter variable usage in TS files.
- Keep a cheat-sheet of semantic variable names accessible during development.
When it happens
Trigger: A .ts or .tsx file under src/renderer/ contains code like style={{ background: 'var(--color-primary-500)' }}, document.body.style.setProperty('--color-blue-500', value), or a template string referencing a --color-* token. The validator parses the TS AST and inspects all string-like nodes.
Common situations: An inline style in a React component referencing a raw --color-* token instead of a semantic variable. Dynamic style manipulation via setProperty or CSSStyleSheet API using adapter variables. String interpolation constructing a CSS value with --color-* tokens. Copy-pasting adapter variable names from generated CSS into component code.
Related errors
- [theme-contract] renderer stylesheet ${fileName} cannot use
- [theme-contract] renderer theme must use the shared generate
- [theme-contract] renderer TypeScript source ${fileName} cann
- [theme-contract] ${sourceName} declares invalid custom prope
- [theme-contract] ${sourceName} references invalid custom pro
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/7a2c2495ccb25eb7.
Report an issue: GitHub.