{"record":{"id":"dfd3c05eb0ae786e","repo":"denoland/deno","slug":"invalid-attribute-for-buf-modifier","errorCode":null,"errorMessage":"invalid attribute for `{buf}` modifier","messagePattern":"invalid attribute for `(.+?)` modifier","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"libs/ops/op2/signature.rs","lineNumber":1412,"sourceCode":"        )));\n      }\n    }\n\n    buf @ \"buffer\" | buf @ \"anybuffer\" | buf @ \"arraybuffer\" => {\n      let mode = if matches!(attr.meta, Meta::Path(_)) {\n        BufferMode::Default\n      } else {\n        let ident: Ident = attr\n          .parse_args()\n          .map_err(AttributeError::InvalidAttribute)?;\n        if ident == \"unsafe\" {\n          BufferMode::Unsafe\n        } else if ident == \"copy\" {\n          BufferMode::Copy\n        } else if ident == \"detach\" {\n          BufferMode::Detach\n        } else {\n          return Err(AttributeError::InvalidAttribute(syn::Error::new(\n            attr.span(),\n            format!(\"invalid attribute for `{buf}` modifier\"),\n          )));\n        }\n      };\n\n      let source = match buf {\n        \"buffer\" => BufferSource::TypedArray,\n        \"anybuffer\" => BufferSource::Any,\n        \"arraybuffer\" => BufferSource::ArrayBuffer,\n        _ => unreachable!(),\n      };\n\n      Some(AttributeModifier::Buffer(mode, source))\n    }\n\n    // async is a keyword and does not work as #[async] so we use #[async_method] instead\n    \"required\" | \"rename\" | \"method\" | \"getter\" | \"setter\" | \"fast\"","sourceCodeStart":1394,"sourceCodeEnd":1430,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/libs/ops/op2/signature.rs#L1394-L1430","documentation":"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.","triggerScenarios":"`#[buffer(shared)]`, `#[buffer(zero_copy)]`, `#[arraybuffer(resizable)]`, or a misspelling like `#[buffer(coppy)]`; also multiple arguments where one identifier is expected.","commonSituations":"Coming from other binding frameworks that have `shared`/`zero_copy` buffer modes and guessing those names; typos.","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."],"exampleFix":"// before\n#[op2]\nfn op_write(#[buffer(zero_copy)] buf: &[u8]) { /* ... */ }\n\n// after\n#[op2]\nfn op_write(#[buffer(unsafe)] buf: &[u8]) { /* ... */ }","handlingStrategy":"validation","validationCode":"// Compile-time: `cargo check`. Closed set per buffer modifier:\n//   #[buffer] | #[buffer(unsafe)] | #[buffer(copy)] | #[buffer(detach)]\n//   (same for anybuffer / arraybuffer)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["op2","proc-macro","buffer","invalid-modifier","compile-time"],"backgroundTag":"invalid-macro-modifier-value","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}