denoland/deno · error · syn::Error
invalid attribute for `{buf}` modifier
Error message
invalid attribute for `{buf}` modifier What it means
For the `buffer`, `anybuffer`, and `arraybuffer` modifiers, op2 accepts a bare form (BufferMode::Default) or exactly one of the identifiers `unsafe`, `copy`, or `detach` in parentheses. The parser at libs/ops/op2/signature.rs raises this formatted error (naming the concrete modifier, e.g. `buffer`) for any other argument.
Source
Thrown at libs/ops/op2/signature.rs:1412
)));
}
}
buf @ "buffer" | buf @ "anybuffer" | buf @ "arraybuffer" => {
let mode = if matches!(attr.meta, Meta::Path(_)) {
BufferMode::Default
} else {
let ident: Ident = attr
.parse_args()
.map_err(AttributeError::InvalidAttribute)?;
if ident == "unsafe" {
BufferMode::Unsafe
} else if ident == "copy" {
BufferMode::Copy
} else if ident == "detach" {
BufferMode::Detach
} else {
return Err(AttributeError::InvalidAttribute(syn::Error::new(
attr.span(),
format!("invalid attribute for `{buf}` modifier"),
)));
}
};
let source = match buf {
"buffer" => BufferSource::TypedArray,
"anybuffer" => BufferSource::Any,
"arraybuffer" => BufferSource::ArrayBuffer,
_ => unreachable!(),
};
Some(AttributeModifier::Buffer(mode, source))
}
// async is a keyword and does not work as #[async] so we use #[async_method] instead
"required" | "rename" | "method" | "getter" | "setter" | "fast"View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Pick one of the three supported modes: `#[buffer(unsafe)]` (borrow without copy), `#[buffer(copy)]` (copy into Rust-owned memory), `#[buffer(detach)]` (take ownership by detaching the ArrayBuffer), or drop the parentheses for the default.
- Check spelling — the argument is a bare identifier matched by string equality (`unsafe`, `copy`, `detach`).
- Remember the modifier name in the message tells you which attribute (`buffer`, `anybuffer`, or `arraybuffer`) got the bad argument.
Example fix
// before
#[op2]
fn op_write(#[buffer(zero_copy)] buf: &[u8]) { /* ... */ }
// after
#[op2]
fn op_write(#[buffer(unsafe)] buf: &[u8]) { /* ... */ } Defensive patterns
Strategy: validation
Validate before calling
// Compile-time: `cargo check`. Closed set per buffer modifier: // #[buffer] | #[buffer(unsafe)] | #[buffer(copy)] | #[buffer(detach)] // (same for anybuffer / arraybuffer)
Prevention
- Memorize the three modes (`unsafe`, `copy`, `detach`) — there is no `shared` or `zero_copy`.
- Pick the mode consciously per op: `unsafe` borrows, `copy` clones, `detach` consumes the ArrayBuffer.
When it happens
Trigger: `#[buffer(shared)]`, `#[buffer(zero_copy)]`, `#[arraybuffer(resizable)]`, or a misspelling like `#[buffer(coppy)]`; also multiple arguments where one identifier is expected.
Common situations: Coming from other binding frameworks that have `shared`/`zero_copy` buffer modes and guessing those names; typos.
Related errors
- invalid attribute for `string` modifier
- Only ASCII keys are supported
- The flags for this attribute were not sorted alphabetically.
- expected attribute arguments in parentheses: `{}(...)`
- Expected a function or impl block for #[op2]
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/dfd3c05eb0ae786e.
Report an issue: GitHub.