{"record":{"id":"5139723259b6e12b","repo":"tailwindlabs/tailwindcss","slug":"utility-node-params-defines-an-invalid-utili-513972","errorCode":null,"errorMessage":"`@utility ${node.params}` defines an invalid utility name. The dynamic portion marked by `-*` must appear once at the end.","messagePattern":"`@utility (.+?)` defines an invalid utility name\\. The dynamic portion marked by `-\\*` must appear once at the end\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tailwindcss/src/index.ts","lineNumber":245,"sourceCode":"      }\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\n        throw new Error(\n          `\\`@utility ${node.params}\\` defines an invalid utility name. Utilities should be alphanumeric and start with a lowercase letter.`,\n        )\n      }\n\n      customUtilities.push(utility)\n    }\n\n    // Collect paths from `@source` at-rules\n    if (node.name === '@source') {\n      if (node.nodes.length > 0) {\n        throw new Error('`@source` cannot have a body.')\n      }\n\n      if (ctx.parent !== null) {","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/tailwindlabs/tailwindcss/blob/16e94cbf7f965c5ad697e90e940b5e178efad67c/packages/tailwindcss/src/index.ts#L227-L263","documentation":"Thrown from the fallback chain when `createCssUtility(node)` returns null, the params do not end with `*`, but they contain a `*` somewhere in the middle. Because the dynamic marker must appear once at the end of a functional utility, an interior `*` (e.g. `foo-*-bar`, `*foo`, `a*b`) is ambiguous and rejected.","triggerScenarios":"Defining a functional utility with the wildcard anywhere other than the very end, e.g. `@utility icon-*-${size}`, `@utility *-hidden`, or `@utility cell-*-*` (the latter ends with `-*` so it actually falls through to error 66 — see notes).","commonSituations":"Trying to express multiple dynamic segments; copying glob patterns verbatim into `@utility` names.","solutions":["Move the dynamic portion to the end as a single `-*`, e.g. `@utility icon-*` and encode other dimensions via the body or separate utilities.","Drop the `*` if the name should be static.","Split a multi-dimensional utility into several single-slot `@utility` rules."],"exampleFix":"/* before */\n@utility icon-*-${size} {\n  /* ... */\n}\n\n/* after */\n@utility icon-* {\n  /* encode size another way, e.g. separate utilities icon-sm, icon-md */\n}","handlingStrategy":"validation","validationCode":"// Catch a wildcard that is not at the end.\nfunction validateNoInteriorWildcard(name: string): string | null {\n  if (name.includes('*') && !name.endsWith('*')) {\n    return `Wildcard in '${name}' must appear once at the end as -*`\n  }\n  return null\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never place a `*` in the middle of a utility name; encode multi-dimensional variants as separate utilities.","Lint `@utility` params for any `*` not in trailing `-*` position.","Document your team's functional-utility naming convention in a CONTRIBUTING file."],"tags":["at-utility","functional-utility","naming","wildcard"],"backgroundTag":null,"analyzedSha":"16e94cbf7f965c5ad697e90e940b5e178efad67c","analyzedAt":"2026-08-12T06:02:42.469Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}