{"record":{"id":"a39ffacb448585b7","repo":"tailwindlabs/tailwindcss","slug":"utility-node-params-is-empty-utilities-shou","errorCode":null,"errorMessage":"`@utility ${node.params}` is empty. Utilities should include at least one property.","messagePattern":"`@utility (.+?)` is empty\\. Utilities should include at least one property\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tailwindcss/src/index.ts","lineNumber":230,"sourceCode":"          root = {\n            base: (ctx.context.sourceBase as string) ?? (ctx.context.base as string),\n            pattern: path.slice(1, -1),\n          }\n        }\n      }\n\n      utilitiesNode = node\n      features |= Features.Utilities\n    }\n\n    // Collect custom `@utility` at-rules\n    if (node.name === '@utility') {\n      if (ctx.parent !== null) {\n        throw new Error('`@utility` cannot be nested.')\n      }\n\n      if (node.nodes.length === 0) {\n        throw new Error(\n          `\\`@utility ${node.params}\\` is empty. Utilities should include at least one property.`,\n        )\n      }\n\n      let utility = createCssUtility(node)\n      if (utility === null) {\n        if (!node.params.endsWith('-*')) {\n          if (node.params.endsWith('*')) {\n            throw new Error(\n              `\\`@utility ${node.params}\\` defines an invalid utility name. A functional utility must end in \\`-*\\`.`,\n            )\n          } else if (node.params.includes('*')) {\n            throw new Error(\n              `\\`@utility ${node.params}\\` defines an invalid utility name. The dynamic portion marked by \\`-*\\` must appear once at the end.`,\n            )\n          }\n        }\n","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/tailwindlabs/tailwindcss/blob/16e94cbf7f965c5ad697e90e940b5e178efad67c/packages/tailwindcss/src/index.ts#L212-L248","documentation":"Thrown when an `@utility` at-rule has zero child nodes (`node.nodes.length === 0`). Tailwind requires every utility to declare at least one CSS property so it produces output; an empty block is almost always a typo or an unfinished edit. The check runs after the nesting guard and before `createCssUtility`.","triggerScenarios":"Writing `@utility card { }` with no declarations, or a block containing only comments/whitespace that parse to zero nodes.","commonSituations":"Stubbing out a utility placeholder and forgetting to fill it; deleting the body during a refactor and leaving the at-rule behind; copy-paste that dropped the inner rules.","solutions":["Add at least one CSS declaration inside the block, e.g. `@utility card { padding: 1rem; }`.","If the utility is no longer needed, remove the entire `@utility` at-rule.","Re-check that your editor/CI did not strip the body during formatting."],"exampleFix":"/* before */\n@utility card { }\n\n/* after */\n@utility card {\n  padding: 1rem;\n  border-radius: 0.5rem;\n}","handlingStrategy":"validation","validationCode":"// Reject empty @utility blocks before compiling.\nimport postcss from 'postcss'\n\nfunction validateUtilityHasBody(css: string): string[] {\n  const errors: string[] = []\n  postcss.parse(css).walkAtRules('@utility', (rule) => {\n    if (rule.nodes.length === 0) {\n      errors.push(`@utility ${rule.params} is empty`)\n    }\n  })\n  return errors\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat `@utility name {}` as a typo in code review.","Add an editor snippet that always inserts at least one placeholder declaration.","Lint for empty at-rule blocks in CI."],"tags":["at-utility","empty-block","validation"],"backgroundTag":null,"analyzedSha":"16e94cbf7f965c5ad697e90e940b5e178efad67c","analyzedAt":"2026-08-12T06:02:42.469Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}