Skip to content

Please give me details related to our code for "Unknown word" error. #16447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Nefcanto opened this issue Feb 12, 2025 · 15 comments
Open

Please give me details related to our code for "Unknown word" error. #16447

Nefcanto opened this issue Feb 12, 2025 · 15 comments

Comments

@Nefcanto
Copy link

After upgrading to Tailwind 4, I'm getting this error in my Qwik + Tailwind app:

x Build failed in 4.66s
error during build:
[vite:css] [postcss] /Project/SiteQwik/src/global.css:3444:27: Unknown word
file: /Project/SiteQwik/src/global.css:3444:26
    at Input.error (/npm/node_modules/postcss/lib/input.js:109:16)
    at Parser.unknownWord (/npm/node_modules/postcss/lib/parser.js:593:22)
    at Parser.other (/npm/node_modules/postcss/lib/parser.js:435:12)
    at Parser.parse (/npm/node_modules/postcss/lib/parser.js:470:16)
    at parse (/npm/node_modules/postcss/lib/parse.js:11:12)
    at new LazyResult (/npm/node_modules/postcss/lib/lazy-result.js:133:16)
    at Processor.process (/npm/node_modules/postcss/lib/processor.js:53:14)
    at compileCSS (file:///npm/node_modules/vite/dist/node/chunks/dep-CHZK6zbr.js:36898:59)
    at async Object.transform (file:///npm/node_modules/vite/dist/node/chunks/dep-CHZK6zbr.js:36171:11)
    at async transform (file:///npm/node_modules/rollup/dist/es/shared/node-entry.js:20698:16)

❌ Error: Client build failed: Error: Command failed with exit code 1: npm run build.client

node:internal/modules/cjs/loader:1247
  throw err;

The problem is that it does not tell us where. As a developer I need to know some info related to MY code in order to be able to track the problem and solve it.

Please give us some info related to our code in this error.

@Nefcanto
Copy link
Author

The least amount of information could be the word itself. I think that could also help.

@wongjn
Copy link
Collaborator

wongjn commented Feb 12, 2025

From the error tag and the stack trace, the error is coming from PostCSS code, not Tailwind, so this might need to be directed at that project instead.

Could also be related to #15853 and #16358.

@philipp-spiess
Copy link
Member

Hey! There is likely something detected as an arbitrary candidate that produces invalid CSS. Unfortunately it seems like downstream tools like PostCSS will choke on that completely without giving you more information :/

Since I see that you're using Vite, you could try adding this Vite plugin to print the interim CSS and then send it to us so we can take a look at what the faulty line is? Definitely something we should handle better!

/* vite.config.ts */
import tailwindcss from '@tailwindcss/vite'
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'

  export default defineConfig({
    plugins: [
      react(), 
      tailwindcss(), 
+     inspect(),
    ],
  })

+ function inspect() {
+   return {
+     name: 'vite-plugin-inspect',
+     enforce: 'pre',
+     transform(css, id) {
+       if (id.endsWith('.css')) {
+         console.log(css)
+       }
+     },
+   }
+ }

@Nefcanto
Copy link
Author

Generate.zip

@philipp-spiess the plugin you said created 10 thousand lines of code. Almost half a megabyte. I had to zip it.

@wongjn
Copy link
Collaborator

wongjn commented Feb 12, 2025

I would expect it would be because of:

.after\:content-\[\&quot\;\&quot\;\] {
  &::after {
    content: var(--tw-content);
    --tw-content: " " !important;
    content: var(--tw-content) !important;
  }
}

Like the two issues mentioned previously, HTML entities seem to be tripping PostCSS up.

@Nefcanto
Copy link
Author

@wongjn any idea how can we prevent these types of classes from being written by our developers? I mean, we literally create hundreds of websites for customers and many developers are working. We don't know what utilities they use. We need to somehow find out what can cause problems.

Can I prevent all after and before variants? We have a static code analyzer in Python.

@wongjn
Copy link
Collaborator

wongjn commented Feb 12, 2025

I don't think developers are writing that class name. It would most likely be from after:content-[""] class name that gets HTML entity encoded by the build system. Not sure if it would be only the before and after variants, but any character within arbitrary values/variants/properties that have a character that would be HTML-entity-encoded (by Qwik in your particular case).

@philipp-spiess
Copy link
Member

@Nefcanto Mind sharing your Vite config? I suppose that something is converting " to " before Tailwind CSS sees the stylesheets. If you have more than one plugin in your Vite config, ensure tailwindcss() comes first.

@Nefcanto
Copy link
Author

@philipp-spiess, sure:

export default defineConfig(({ mode }) => {

    function inspect() {
        return {
            name: 'vite-plugin-inspect',
            enforce: 'pre',
            transform(css, id) {
                if (id.endsWith('.css')) {
                    console.log(css)
                }
            },
        }
    }

    return {
        plugins: [
            tailwindcss(),
            qwikCity({
                trailingSlash: false
            }),
            qwikVite({
                devTools: {
                    imageDevTools: false,
                },
            }),
            tsconfigPaths(),
            partytownVite({ dest: join(__dirname, "dist", "~partytown") }),
        ],
        dev: {
            headers: {
                "Cache-Control": "public, max-age=0",
            },
        },
        server: {
            headers: {
                "Cache-Control": "public, max-age=0",
            },
            host: "0.0.0.0",
            hmr: {
                clientPort: 443,
            },
            allowedHosts: true
        },
        preview: {
            headers: {
                "Cache-Control": "public, max-age=600",
            },
        },
        build: {
            rollupOptions: {
                external: [
                    ...barrels,
                ]
            },
        },
        optimizeDeps: {
            exclude: []
        }
    }
})

@ojvribeiro
Copy link

ojvribeiro commented Feb 18, 2025

One thing I noticed was that this error is thrown when we have line breaks between the classes in a template string like this (Nuxt 3, simplified code):

<script setup>
  import { twMerge } from 'tailwind-merge'

  const resolvedClasses = computed(() => {
    const defaultClasses = `
      text-2xl
      bg-red-400
    ` // <-- this causes the error

    return twMerge([
      // ...
      defaultClasses,
    ])
  })
</script>

<template>
  <div :class="resolvedClasses" />
</template>

It was hard to find this in a big codebase. To solve this I just put the classes in a single line and the error was gone.

<script setup>
  import { twMerge } from 'tailwind-merge'

  const resolvedClasses = computed(() => {
    const defaultClasses = 'text-2xl bg-red-400' // <-- this solves the error

    return twMerge([
      // ...
      defaultClasses,
    ])
  })
</script>

<template>
  <div :class="resolvedClasses" />
</template>

It worked just fine in v3.

@hiepxanh
Copy link

hiepxanh commented Feb 19, 2025

the complex of css cause this issue, error cause by user try to use weird class so parser failed at production (postcss-parser).

I have successful debug here:

step 1: verbose build

pnpm nx build chatter-web --verbose

 NX   <css input>:1:172168: Unknown word
CssSyntaxError: <css input>:1:172168: Unknown word
    at Input.error (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\input.js:109:16)
    at Parser.unknownWord (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\parser.js:612:22)
    at Parser.other (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\parser.js:437:12)
    at Parser.parse (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\parser.js:488:16)
    at Function.parse (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\parse.js:11:12)
    at parseStylesheet (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\beasties@0.2.0\node_modules\beasties\dist\index.cjs:22:18)
    at BeastiesExtended.processStyle (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\beasties@0.2.0\node_modules\beasties\dist\index.cjs:771:17)   
    at BeastiesExtended.process (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\beasties@0.2.0\node_modules\beasties\dist\index.cjs:549:12)        
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)

verbose show that issue at postcss, try to overide it to show detail token

step 2: Ctrl + Click at each function to see where to put logs

CssSyntaxError: <css input>:1:172168: Unknown word
    at Input.error (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\input.js:109:16)
    at Parser.unknownWord (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\parser.js:612:22)
    at Parser.other (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\parser.js:437:12)
    at Parser.parse (C:\Users\hiepx\small-cosmos\losa\node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\parser.js:488:16) <---  CTRL + CLICK HERE (only work with vscode build terminal)

this will open this file: node_modules\.pnpm\postcss@8.5.2\node_modules\postcss\lib\parser.js:488:16 (you can remove .pnpm if using other package manager`

step 3: add debug code

 parse() {
    let token
    while (!this.tokenizer.endOfFile()) {
      token = this.tokenizer.nextToken()
        // START Add debug logging with safe access
        const currentIndex = this.tokenizer.current || 0
        const tokens = this.tokenizer.tokens || []
        
        console.log('Current token:', JSON.stringify(token))
        console.log('Current index:', currentIndex)
        
        if (currentIndex > 0) {
            console.log('Previous token:', JSON.stringify(tokens[currentIndex - 1]))
        }
        
        if (currentIndex < tokens.length - 1) {
            console.log('Next token:', JSON.stringify(tokens[currentIndex + 1]))
        }
        
        console.log('END HERE -------------------')

      switch (token[0]) {
        case 'space':
          this.spaces += token[1]
          break

output:

-------------------
Current token: ["word","margin",172024,172029]
Current index: 0
-------------------
Current token: ["}","}",172055]
Current index: 0
-------------------
Current token: ["}","}",172056]
Current index: 0
-------------------
Current token: ["word",".",172057,172057]
Current index: 0
-------------------
Current token: ["word","grid-column",172086,172096]
Current index: 0
-------------------
Current token: ["}","}",172123]
Current index: 0
-------------------
Current token: ["word",".",172124,172124]
Current index: 0
-------------------
Current token: ["word","&amp",172167,172170]
Current index: 0
-------------------
 NX   <css input>:1:172168: Unknown word
CssSyntaxError: <css input>:1:172168: Unknown word

the error show at &amp, you can search it now and try to remove it. BTW, the above code is try to locate relate css code above the error character, which help you try to locate it better. That how I fix it at my angular code

the bug have: & character which complie to &amp, so I try to search all & at html file and it work.


    <span
      style="opacity: 1"
      class="[&amp;::selection]:text-base-content"
    >
      Không cần niệm chú
    </span>
  

Thanks claude AI to help write console log (:v)

@Nefcanto
Copy link
Author

@hiepxanh the point is that we can't do that every time we see this error. The logs you set there are ephemeral. They won't be there next time you run a new container (we develop inside containers). But for one time, that's an interesting approach.

@Nefcanto
Copy link
Author

@adamwathan, could you please persuade the PostCSS team to clarify their logs? I asked there: postcss/postcss#2014 but the communication did not go smoothly.

As @hiepxanh showed above, the parser of PostCSS is where they should add a simple log for the problematic token.

@kaceo
Copy link

kaceo commented Mar 8, 2025

As a Nuxt3 user I started encountering this error once I upgrade to @nuxt/ui@3.0.0-beta.2, which includes the Tailwindcss 4.0.x release as a dependency.

My main.css has the following lines to embed the tailwindcss:

@import "tailwindcss" theme(static);
@import "@nuxt/ui";

This results in the following compilation error:

  ERROR  Internal server error: [postcss] /code/tangodata/try/layers/90_base/app/assets/css/tailwind.css:3133:27: Unknown word &quot
  Plugin: vite:css
  File: /code/tangodata/try/layers/90_base/app/assets/css/tailwind.css:3133:26
      at Input.error (/code/tangodata/try/node_modules/.pnpm/postcss@8.5.3/node_modules/postcss/lib/input.js:113:16)
      at Parser.unknownWord (/code/tangodata/try/node_modules/.pnpm/postcss@8.5.3/node_modules/postcss/lib/parser.js:595:22)

Following some issues discussion (nuxt/ui#3374), it was suggested to change the main.css to the following form:

@layer theme, base, components, utilities;
@import 'tailwindcss/theme' layer(theme) theme(static);
@import 'tailwindcss/preflight' layer(base);
@import 'tailwindcss/utilities' layer(utilities);
@import '@nuxt/ui';

This also fails, but if the fourth line is commented out then no compilation error from postcss:

/* @import 'tailwindcss/utilities' layer(utilities); */

So I guess there is an error in the utilities layer that needs to be fixed.

@Bhavdeep-Sai
Copy link

Fixed by updating tailwind.config.js content paths

I resolved the issue by ensuring that my tailwind.config.js has the correct content paths. Tailwind was purging styles in production because it couldn’t find the class names.

Here’s what I updated:

// tailwind.config.js
module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}", // adjust to your project structure
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Also, avoid dynamic class names like text-${size} unless you safelist them. Rebuild your project after the update.

Hope this helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants