{"record":{"id":"4d62fc0fe02af158","repo":"CherryHQ/cherry-studio","slug":"theme-contract-unsupported-import-syntax-imp","errorCode":null,"errorMessage":"[theme-contract] unsupported @import syntax: ${importValue}","messagePattern":"\\[theme-contract\\] unsupported @import syntax: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/scripts/validate-theme-contract.ts","lineNumber":102,"sourceCode":"  return [...value.matchAll(/var\\(\\s*(--[^\\s,)]+)/g)].map((match) => {\n    const name = match[1]\n    if (!CUSTOM_PROPERTY_NAME_PATTERN.test(name)) {\n      throw new Error(`[theme-contract] ${sourceName} references invalid custom property ${name}`)\n    }\n    return name\n  })\n}\n\nfunction extractImports(source: string): string[] {\n  return [...stripComments(source).matchAll(/@import\\s+([^;]+);/g)].map((match) => {\n    const importValue = match[1].trim()\n    const stringMatch = importValue.match(/^(['\"])([^'\"]+)\\1$/)\n    if (stringMatch) return stringMatch[2]\n\n    const urlMatch = importValue.match(/^url\\(\\s*(?:(['\"])([^'\"]+)\\1|([^'\")\\s][^)]*?))\\s*\\)$/)\n    if (urlMatch) return (urlMatch[2] ?? urlMatch[3]).trim()\n\n    throw new Error(`[theme-contract] unsupported @import syntax: ${importValue}`)\n  })\n}\n\nfunction assertUnique(label: string, values: readonly string[]): void {\n  if (new Set(values).size !== values.length) {\n    throw new Error(`[theme-contract] ${label} contains duplicate names`)\n  }\n}\n\nfunction assertSurfacePairs(\n  label: string,\n  pairs: ReadonlyArray<readonly [surface: string, foreground: string]>,\n  variableNames: Set<string>\n): void {\n  const surfaces = new Set<string>()\n\n  for (const [surface, foreground] of pairs) {\n    if (surface === foreground || surfaces.has(surface)) {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/packages/ui/scripts/validate-theme-contract.ts#L84-L120","documentation":"Thrown by the theme contract validator when an @import statement in a CSS file uses a syntax that is neither a quoted string (e.g., @import 'file.css'; or @import \"file.css\";) nor a url() function (e.g., @import url('file.css');). The extractImports function matches @import followed by a quoted string or url(...) and throws for any other format. This enforces a consistent import style and catches malformed @import statements.","triggerScenarios":"A CSS file contains an @import with an unquoted bare path (e.g., @import file.css;), an @import with media queries written inline without proper wrapping, or a syntax that doesn't match the string or url() patterns. The validator processes every @import \\s+([^;]+); match and rejects unparseable values.","commonSituations":"A developer writes @import without quotes (@import tokens/colors.css;). A CSS minifier or formatter rewrites @import into an unexpected format. An @import with a layer() or supports() qualifier that shifts the string/url match. A merge conflict artifact producing a broken @import.","solutions":["Rewrite the @import to use a quoted string: @import 'path/to/file.css';.","If using url() syntax, ensure it's properly formatted: @import url('path/to/file.css');.","If the @import has qualifiers (layer, supports), move them outside the string so the path itself is quoted: @import 'file.css' layer(theme);.","Run the validator to confirm: npx tsx packages/ui/scripts/validate-theme-contract.ts."],"exampleFix":"/* before — unquoted import */\n@import tokens/colors.css;\n\n/* after — quoted string */\n@import 'tokens/colors.css';","handlingStrategy":"validation","validationCode":"// Validate @import syntax in CSS before committing\nimport { readFileSync } from 'node:fs'\n\nfunction checkImports(cssPath: string): void {\n  const source = readFileSync(cssPath, 'utf8').replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n  const imports = [...source.matchAll(/@import\\s+([^;]+);/g)]\n  for (const match of imports) {\n    const value = match[1].trim()\n    const isString = /^(['\"])([^'\"]+)\\1$/.test(value)\n    const isUrl = /^url\\(\\s*(?:(['\"])([^'\"]+)\\1|([^'\")\\s][^)]*?))\\s*\\)$/.test(value)\n    if (!isString && !isUrl) {\n      throw new Error(`${cssPath}: unsupported @import syntax: ${value}`)\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write @import with a quoted string path: @import 'file.css'; or @import \"file.css\";.","If using url() syntax, ensure proper formatting: @import url('file.css');.","Place layer()/supports() qualifiers after the quoted path, not inside it.","Run the theme contract validator in CI to catch malformed @import statements."],"tags":["theme-contract","build-validation","css","import","syntax"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}