Skip to content

Commit 939fda6

Browse files
Show more specific error for functional-like but invalid utility names (#18568)
Fixes #18566 The behavior is by design but the error message could definitely be improved.
1 parent 298ad08 commit 939fda6

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Ignore consecutive semicolons in the CSS parser ([#18532](https://github.com/tailwindlabs/tailwindcss/pull/18532))
1818
- Center the dropdown icon added to an input with a paired datalist ([#18511](https://github.com/tailwindlabs/tailwindcss/pull/18511))
1919
- Extract candidates in Slang templates ([#18565](https://github.com/tailwindlabs/tailwindcss/pull/18565))
20+
- Improve error messages when encountering invalid functional utility names ([#18568](https://github.com/tailwindlabs/tailwindcss/pull/18568))
2021

2122
## [4.1.11] - 2025-06-26
2223

packages/tailwindcss/src/index.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4354,6 +4354,30 @@ describe('@utility', () => {
43544354
`[Error: \`@utility 💨\` defines an invalid utility name. Utilities should be alphanumeric and start with a lowercase letter.]`,
43554355
)
43564356
})
4357+
4358+
test('A functional @utility must end in -*', () => {
4359+
return expect(
4360+
compileCss(css`
4361+
@utility foo* {
4362+
color: red;
4363+
}
4364+
`),
4365+
).rejects.toThrowErrorMatchingInlineSnapshot(
4366+
`[Error: \`@utility foo*\` defines an invalid utility name. A functional utility must end in \`-*\`.]`,
4367+
)
4368+
})
4369+
4370+
test('Only the last part of a functional @utility can be dynamic', () => {
4371+
return expect(
4372+
compileCss(css`
4373+
@utility my-*-utility {
4374+
color: red;
4375+
}
4376+
`),
4377+
).rejects.toThrowErrorMatchingInlineSnapshot(
4378+
`[Error: \`@utility my-*-utility\` defines an invalid utility name. The dynamic portion marked by \`-*\` must appear once at the end.]`,
4379+
)
4380+
})
43574381
})
43584382

43594383
test('addBase', async () => {

packages/tailwindcss/src/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,18 @@ async function parseCss(
229229

230230
let utility = createCssUtility(node)
231231
if (utility === null) {
232+
if (!node.params.endsWith('-*')) {
233+
if (node.params.endsWith('*')) {
234+
throw new Error(
235+
`\`@utility ${node.params}\` defines an invalid utility name. A functional utility must end in \`-*\`.`,
236+
)
237+
} else if (node.params.includes('*')) {
238+
throw new Error(
239+
`\`@utility ${node.params}\` defines an invalid utility name. The dynamic portion marked by \`-*\` must appear once at the end.`,
240+
)
241+
}
242+
}
243+
232244
throw new Error(
233245
`\`@utility ${node.params}\` defines an invalid utility name. Utilities should be alphanumeric and start with a lowercase letter.`,
234246
)

0 commit comments

Comments
 (0)