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

  1. Replace the --color-* reference in the TS string with the semantic variable name (e.g., '--color-primary-500' → '--primary').
  2. If applying the color via inline styles, use the semantic CSS variable: style={{ color: 'var(--primary)' }}.
  3. If the value should be a Tailwind utility class, use the className instead (e.g., className="text-primary").
  4. 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

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


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