neon-bindings/neon · error
Unknown class attribute
Error message
Unknown class attribute '{}' What it means
This is a compile-time error from Neon's `#[neon]` macro when parsing the attribute list inside `export(class(...))`. The macro only recognizes `name` as a valid attribute inside the parentheses; any other identifier is rejected. It ensures typo'd or unsupported class options fail fast instead of being silently ignored.
Solutions
- Replace the unknown attribute with `name`: `export(class(name = "ClassName"))`.
- Check the Neon docs for the exact set of supported `class` attributes (only `name` is currently accepted).
- If you intended to rename the module export binding rather than the class itself, move the `name = "..."` attribute outside the parentheses: `export(class, name = "binding")`.
Example fix
// before #[neon] export(class(rename = "MyClass")) // after #[neon] export(class(name = "MyClass"))
Defensive patterns
Strategy: validation
Validate before calling
// Only `name` is a valid attribute inside export(class(...)):
// verify every key you write in class(...) is exactly `name`:
// #[neon] export(class(name = "..."))
const VALID_CLASS_ATTRS: [&str; 1] = ["name"];
fn check_attr(attr: &str) -> Result<(), String> {
if VALID_CLASS_ATTRS.contains(&attr) { Ok(()) } else { Err(format!("Unknown class attribute '{}'", attr)) }
} Prevention
- Use only documented attributes; inside class(...) the sole supported key is `name`.
- Copy attribute syntax from official Neon examples rather than other macro frameworks.
- Run `cargo check` after editing attribute macros to catch parse errors early.
When it happens
Trigger: Writing `#[neon] export(class(rename = "Foo"))` or any attribute key other than `name` inside the `class(...)` parentheses of the export attribute, e.g. `export(class(fname = "X"))`.
Common situations: Developers guessing at attribute names (e.g. `class_name`, `rename`, `jsName`) based on other macro systems, copying patterns from `export(fn)` attributes, or upgrading Neon versions where an attribute may have been renamed or removed.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Unknown attribute
- Expected an owned `Channel` instead of a context reference.
- Context is not available in async functions. Try a…
- Expected a context argument after `&self` when using…
- Unexpected second receiver argument.
AI-assisted analysis of neon-bindings/neon@38960e4381 (2026-09-13).
Data as JSON: /api/errors/73e4561d09db86ba.
Report an issue: GitHub.
Appendix: source
Thrown at crates/neon-macros/src/export/class/meta.rs:41
let mut meta = Meta::default();
// Check for parenthesized attributes: class(name = "...")
if input.peek(syn::token::Paren) {
let content;
syn::parenthesized!(content in input);
// Parse attributes inside parentheses
while !content.is_empty() {
let name_token: syn::Ident = content.parse()?;
match name_token.to_string().as_str() {
"name" => {
content.parse::<syn::Token![=]>()?;
let name_value: syn::LitStr = content.parse()?;
meta.class_name = Some(name_value.value());
}
_ => {
return Err(syn::Error::new(
name_token.span(),
format!("Unknown class attribute '{}'", name_token),
));
}
}
// Parse optional comma
if content.parse::<syn::Token![,]>().is_err() {
break;
}
}
}
// Check if there are additional attributes after "class" or "class(...)"
if input.parse::<syn::Token![,]>().is_ok() {
// Parse additional attributes like name = "..."
while !input.is_empty() {
let name_token: syn::Ident = input.parse()?;View on GitHub (pinned to 38960e4381)