{"record":{"id":"a8153606b387f705","repo":"tailwindlabs/tailwindcss","slug":"custom-variant-name-has-no-selector-or-body","errorCode":null,"errorMessage":"`@custom-variant ${name}` has no selector or body.","messagePattern":"`@custom-variant (.+?)` has no selector or body\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tailwindcss/src/index.ts","lineNumber":372,"sourceCode":"        throw new Error('`@custom-variant` cannot be nested.')\n      }\n\n      let [name, selector] = segment(node.params, ' ')\n\n      if (!IS_VALID_VARIANT_NAME.test(name)) {\n        throw new Error(\n          `\\`@custom-variant ${name}\\` defines an invalid variant name. Variants should only contain alphanumeric, dashes, or underscore characters and start with a lowercase letter or number.`,\n        )\n      }\n\n      if (node.nodes.length > 0 && selector) {\n        throw new Error(`\\`@custom-variant ${name}\\` cannot have both a selector and a body.`)\n      }\n\n      // Variants with a selector, but without a body, e.g.: `@custom-variant hocus (&:hover, &:focus);`\n      if (node.nodes.length === 0) {\n        if (!selector) {\n          throw new Error(`\\`@custom-variant ${name}\\` has no selector or body.`)\n        }\n\n        let selectors = segment(selector.slice(1, -1), ',')\n        if (selectors.length === 0 || selectors.some((selector) => selector.trim() === '')) {\n          throw new Error(\n            `\\`@custom-variant ${name} (${selectors.join(',')})\\` selector is invalid.`,\n          )\n        }\n\n        let atRuleParams: string[] = []\n        let styleRuleSelectors: string[] = []\n\n        for (let selector of selectors) {\n          selector = selector.trim()\n\n          if (selector[0] === '@') {\n            atRuleParams.push(selector)\n          } else {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/tailwindlabs/tailwindcss/blob/16e94cbf7f965c5ad697e90e940b5e178efad67c/packages/tailwindcss/src/index.ts#L354-L390","documentation":"Thrown when a `@custom-variant` has neither a body (`node.nodes.length === 0`) nor a selector token in its prelude. A custom variant must define at least one of the two, otherwise there is nothing to register.","triggerScenarios":"Writing `@custom-variant hocus;` with no arguments and no body.","commonSituations":"Stubbing a variant name for later; typo that dropped the selector; refactoring that removed the body.","solutions":["Add a selector: `@custom-variant hocus (&:hover, &:focus);`.","Or add a body: `@custom-variant hocus { &:hover { @variant ...; } }`.","If the variant is unused, remove the `@custom-variant` rule entirely."],"exampleFix":"/* before */\n@custom-variant hocus;\n\n/* after */\n@custom-variant hocus (&:hover, &:focus);","handlingStrategy":"validation","validationCode":"// Ensure @custom-variant has a selector or a body.\nimport postcss from 'postcss'\n\nfunction validateCustomVariantHasContent(css: string): string[] {\n  const errors: string[] = []\n  postcss.parse(css).walkAtRules('@custom-variant', (rule) => {\n    const hasBody = rule.nodes.length > 0\n    const hasSelector = rule.params.split(' ').length > 1\n    if (!hasBody && !hasSelector) {\n      errors.push(`@custom-variant ${rule.params} has no selector or body`)\n    }\n  })\n  return errors\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never commit a bare `@custom-variant name;` placeholder.","Use editor snippets that always insert a selector or body stub.","Lint for empty `@custom-variant` declarations in CI."],"tags":["at-custom-variant","empty","validation"],"backgroundTag":null,"analyzedSha":"16e94cbf7f965c5ad697e90e940b5e178efad67c","analyzedAt":"2026-08-12T06:02:42.469Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}