{"record":{"id":"04dc42e99b96946b","repo":"yewstack/yew","slug":"string-literals-must-not-contain-more-than-one-cla","errorCode":null,"errorMessage":"string literals must not contain more than one class (hint: use `{fix}`)","messagePattern":"string literals must not contain more than one class \\(hint: use `(.+?)`\\)","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"packages/yew-macro/src/classes/mod.rs","lineNumber":64,"sourceCode":"    fn parse(input: ParseStream) -> syn::Result<Self> {\n        match input.parse()? {\n            Expr::Lit(ExprLit {\n                lit: Lit::Str(lit_str),\n                ..\n            }) => {\n                let value = lit_str.value();\n                let classes = value.split_whitespace().collect::<Vec<_>>();\n                if classes.len() > 1 {\n                    let fix = classes\n                        .into_iter()\n                        .map(|class| format!(\"\\\"{class}\\\"\"))\n                        .collect::<Vec<_>>()\n                        .join(\", \");\n                    let msg = format!(\n                        \"string literals must not contain more than one class (hint: use `{fix}`)\"\n                    );\n\n                    Err(syn::Error::new(lit_str.span(), msg))\n                } else {\n                    Ok(Self::Lit(lit_str))\n                }\n            }\n            expr => Ok(Self::Expr(Box::new(expr))),\n        }\n    }\n}\n","sourceCodeStart":46,"sourceCodeEnd":73,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew-macro/src/classes/mod.rs#L46-L73","documentation":"`classes!` builds a `yew::html::Classes` value from comma-separated arguments. When an argument is a plain string literal, the macro splits it on whitespace and rejects it if it yields more than one class (classes/mod.rs:52-64), printing a hint with the correct comma-separated form. The check applies only to literals — arbitrary expressions pass through to the runtime `Classes::push`, which does accept multi-class strings.","triggerScenarios":"`classes!(\"btn btn-primary\")` or `class=classes!(\"a b\")` inside `html!` — any single string-literal argument containing two or more whitespace-separated class names.","commonSituations":"Pasting `class=\"btn btn-primary\"` from HTML/JSX templates or Tailwind class lists into `classes!`, or merging several single-class literals into one string during cleanup.","solutions":["Split the literal into comma-separated arguments exactly as the hint shows: `classes!(\"btn\", \"btn-primary\")`","Keep static and dynamic parts separate: `classes!(\"base\", extra)` where `extra` is a runtime value","If the whole list is genuinely one runtime string, pass it as an expression (e.g. a variable or `format!(...)`) so only the runtime path handles it"],"exampleFix":"// before\nhtml! { <div class=classes!(\"btn btn-primary\")>{ \"Save\" }</div> }\n\n// after\nhtml! { <div class=classes!(\"btn\", \"btn-primary\")>{ \"Save\" }</div> }","handlingStrategy":"validation","validationCode":"// When class names arrive as one runtime string, build Classes outside the\n// literal path — runtime pushes accept multi-class strings:\nlet classes = yew::html::Classes::from(\"btn btn-primary\"); // splits on whitespace","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Adopt the one-class-per-literal habit: `classes!(\"btn\", \"btn-primary\")`, especially when pasting class lists from HTML or Tailwind","Keep dynamic classes as separate expression arguments so literals stay single-class","Add a code-review grep for `classes!(\"` lines containing a space to catch pasted multi-class literals"],"tags":["rust","yew","classes","css","html-macro","compile-error"],"backgroundTag":"invalid-macro-argument","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}