{"record":{"id":"8242164cdd28bad8","repo":"tailwindlabs/tailwindcss","slug":"you-cannot-use-apply-inside-keyframes","errorCode":null,"errorMessage":"You cannot use `@apply` inside `@keyframes`.","messagePattern":"You cannot use `@apply` inside `@keyframes`\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tailwindcss/src/apply.ts","lineNumber":36,"sourceCode":"\n  // Track all nodes containing `@apply`\n  let parents = new Set<AstNode>()\n\n  // Track all the dependencies of an `AstNode`\n  let dependencies = new DefaultMap<AstNode, Set<string>>(() => new Set<string>())\n\n  // Track all `@utility` definitions by its root (name)\n  let definitions = new DefaultMap(() => new Set<AstNode>())\n\n  // Collect all new `@utility` definitions and all `@apply` rules first\n  walk([root], (node, ctx) => {\n    if (node.kind !== 'at-rule') return\n\n    // Do not allow `@apply` rules inside `@keyframes` rules.\n    if (node.name === '@keyframes') {\n      walk(node.nodes, (child) => {\n        if (child.kind === 'at-rule' && child.name === '@apply') {\n          throw new Error(`You cannot use \\`@apply\\` inside \\`@keyframes\\`.`)\n        }\n      })\n      return WalkAction.Skip\n    }\n\n    // `@utility` defines a utility, which is important information in order to\n    // do a correct topological sort later on.\n    if (node.name === '@utility') {\n      let name = node.params.replace(/-\\*$/, '')\n      definitions.get(name).add(node)\n\n      // In case `@apply` rules are used inside `@utility` rules.\n      walk(node.nodes, (child) => {\n        if (child.kind !== 'at-rule' || child.name !== '@apply') return\n\n        parents.add(node)\n\n        for (let dependency of resolveApplyDependencies(child, designSystem)) {","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/tailwindlabs/tailwindcss/blob/16e94cbf7f965c5ad697e90e940b5e178efad67c/packages/tailwindcss/src/apply.ts#L18-L54","documentation":"During `@apply` substitution, the AST walker specially handles `@keyframes` rules and forbids any `@apply` at-rule nested inside them. `@keyframes` defines keyframe stops (percentages / `from` / `to`), which cannot themselves receive utility declarations, so applying utilities there is semantically invalid. The walker skips the keyframes subtree after checking, throwing on the first offending `@apply`.","triggerScenarios":"CSS like `@keyframes fade { from { @apply opacity-0; } }`. The `@keyframes` branch at apply.ts:33 walks its children, finds an `@apply` at-rule, and throws at apply.ts:36.","commonSituations":"Trying to animate using utility values inside `@keyframes`, or copy-pasting utility-based rules into a keyframes block during a refactor.","solutions":["Replace the `@apply` inside `@keyframes` with the literal CSS property (e.g. `opacity: 0`).","Define the utility styles in the element/animation target and let `@keyframes` only set raw property values."],"exampleFix":"/* before */\n@keyframes fade {\n  from { @apply opacity-0; }\n  to   { @apply opacity-100; }\n}\n\n/* after */\n@keyframes fade {\n  from { opacity: 0; }\n  to   { opacity: 1; }\n}","handlingStrategy":"validation","validationCode":"import postcss from 'postcss'\nfunction assertNoApplyInKeyframes(css: string) {\n  const root = postcss.parse(css)\n  root.walkAtRules('keyframes', kf => {\n    kf.walkAtRules('apply', () => {\n      throw new Error(`@apply is forbidden inside @keyframes at line ${kf.source?.start?.line}`)\n    })\n  })\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep @keyframes blocks to raw property values only.","Replace any @apply inside keyframes with literal CSS before building.","Lint for @apply nested under @keyframes in CI."],"tags":["apply","keyframes","css-syntax"],"backgroundTag":null,"analyzedSha":"16e94cbf7f965c5ad697e90e940b5e178efad67c","analyzedAt":"2026-08-12T06:02:42.469Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}