denoland/deno · error · syn::Error
expected attribute arguments in parentheses: `{}(...)`
Error message
expected attribute arguments in parentheses: `{}(...)` What it means
`CustomMeta::require_list` in libs/ops/op2/config.rs returns the attribute's parenthesized arguments as a `MetaList`. If the attribute was written as a bare path (or a name=value) with no `(...)` group, `as_meta_list()` yields `None` and this error is raised on the attribute identifier, asking for the `ident(...)` form.
Source
Thrown at libs/ops/op2/config.rs:384
None
};
Ok(CustomMeta { ident, args })
}
}
impl CustomMeta {
pub fn as_meta_list(&self) -> Option<MetaList> {
self.args.clone().map(|(delimiter, tokens)| MetaList {
path: syn::Path::from(self.ident.clone()),
delimiter,
tokens,
})
}
pub fn require_list(&self) -> Result<MetaList, syn::Error> {
self.as_meta_list().ok_or_else(|| {
syn::Error::new(
self.ident.span(),
format!(
"expected attribute arguments in parentheses: `{}(...)`",
self.ident
),
)
})
}
}
impl ToTokens for CustomMeta {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self.as_meta_list() {
Some(list) => {
list.to_tokens(tokens);
}
_ => {
self.ident.to_tokens(tokens);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Add parentheses with the required arguments: `#[op2(webidl(...))]`, `#[op2(validate(...))]` — the error message names the exact identifier it wants arguments for.
- If you intended a flag with no arguments, you are using the wrong flag name; check op2's flag list for the bare-path variant.
- Consult a nearby op in the same crate (ext/ is full of examples) for the argument shape this attribute expects.
Example fix
// before
#[op2(webidl)]
#[string] fn op_get_color(color: &str) -> String { /* ... */ }
// after
#[op2(webidl(default = Color::Red))]
#[string] fn op_get_color(color: &str) -> String { /* ... */ } Defensive patterns
Strategy: validation
Validate before calling
// Compile-time only: keep `cargo check` in CI and read the combined parse errors. // Habit: argument-taking op2 attributes are always written as `name(...)` — never a bare path.
Prevention
- When copying an op2 attribute, copy the full `(...)` group, not just the identifier.
- Look at neighboring ops in ext/ for the exact argument shape before inventing one.
When it happens
Trigger: Writing an op2/webidl sub-attribute that requires arguments without the parentheses, e.g. `#[op2(webidl)]` where the parser needs `webidl(...)` (as consumed via `input.parse::<CustomMeta>()?.require_list()`), or `#[op2(validate)]` instead of `#[op2(validate(path = "..."))]`.
Common situations: Converting a boolean-style flag into an argument-taking one during upgrades; trimming 'unnecessary' parentheses from a copy-pasted attribute; IDE auto-completing the bare path form.
Related errors
- Only ASCII keys are supported
- The flags for this attribute were not sorted alphabetically.
- Expected a function or impl block for #[op2]
- duplicate `default` argument
- duplicate `options` argument
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/a208f090218ad9ff.
Report an issue: GitHub.