tailwindlabs/tailwindcss · error · Error
Unexpected `@plugin` option: Value of declaration `${toCss([
Error message
Unexpected `@plugin` option: Value of declaration `${toCss([decl]).trim()}` is not supported.
Using an object as a plugin option is currently only supported in JavaScript configuration files. What it means
Thrown when parsing a `@plugin` option declaration whose value starts with `{` and ends with `}` — i.e. an object literal. CSS `@plugin` options only support JSON primitives (null, bool, number, quoted string); object values require a JavaScript config file. The full declaration is echoed via `toCss([decl]).trim()`.
Source
Thrown at packages/tailwindcss/src/compat/apply-compat-hooks.ts:101
let parts = segment(value, ',').map((part) => {
part = part.trim()
if (part === 'null') {
return null
} else if (part === 'true') {
return true
} else if (part === 'false') {
return false
} else if (!Number.isNaN(Number(part))) {
return Number(part)
} else if (
(part[0] === '"' && part[part.length - 1] === '"') ||
(part[0] === "'" && part[part.length - 1] === "'")
) {
return part.slice(1, -1)
} else if (part[0] === '{' && part[part.length - 1] === '}') {
throw new Error(
`Unexpected \`@plugin\` option: Value of declaration \`${toCss([decl]).trim()}\` is not supported.\n\nUsing an object as a plugin option is currently only supported in JavaScript configuration files.`,
)
}
return part
})
options[decl.property] = parts.length === 1 ? parts[0] : parts
}
pluginPaths.push([
{
id: pluginPath,
base: ctx.context.base as string,
reference: !!ctx.context.reference,
src: node.src,
},
Object.keys(options).length > 0 ? options : null,View on GitHub (pinned to 16e94cbf7f)
Solutions
- Move that plugin's configuration into a JS/TS config file (`tailwind.config.js`) where object options are supported.
- Flatten the object into primitive declarations the plugin can read, if the plugin accepts that shape.
- Use `plugin.withOptions()` and pass options from JS instead of CSS `@plugin`.
Example fix
// before (CSS)
@plugin "./my-plugin.js" {
theme: { primary: "#f00" };
}
// after (tailwind.config.js)
plugins: [require("./my-plugin.js")({ theme: { primary: "#f00" } })] Defensive patterns
Strategy: validation
Validate before calling
function assertNoObjectOption(node) {
for (const decl of node.nodes ?? []) {
const v = (decl.value ?? '').trim();
if (v[0] === '{' && v[v.length - 1] === '}') {
throw new Error(`Object option ${decl.property} not supported in CSS @plugin; use JS config`);
}
}
} Prevention
- Keep object-shaped plugin options in a JS config file; pass primitives only via CSS `@plugin`.
- Document per-plugin whether its options are CSS-compatible.
When it happens
Trigger: Writing `@plugin "x.js" { config: { key: value } }`. The part-wise parser hits the `{...}` branch and rejects it.
Common situations: Migrating a JS plugin config that uses nested option objects into CSS `@plugin` syntax; assuming CSS plugin options mirror the JS object shape.
Related errors
- `@plugin` must have a path.
- The plugin "${detail.path}" does not accept options
- Cannot apply unprefixed utility class `${candidate}`. Did yo
- Cannot apply utility class `${candidate}` because it has bee
- `@plugin` cannot be nested.
AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12).
Data as JSON: /api/errors/2d1a4819bc14cade.
Report an issue: GitHub.