{"record":{"id":"38f5a4f525d17b4d","repo":"denoland/deno","slug":"invalid-attribute-for-string-modifier","errorCode":null,"errorMessage":"invalid attribute for `string` modifier","messagePattern":"invalid attribute for `string` modifier","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"libs/ops/op2/signature.rs","lineNumber":1391,"sourceCode":"      } else {\n        attr\n          .parse_args()\n          .map_err(AttributeError::InvalidAttribute)?\n      };\n\n      Some(AttributeModifier::WebIDL(args))\n    }\n\n    \"string\" => {\n      if matches!(attr.meta, Meta::Path(_)) {\n        Some(AttributeModifier::String(StringMode::Default))\n      } else if attr\n        .parse_args::<Ident>()\n        .is_ok_and(|mode| mode == \"onebyte\")\n      {\n        Some(AttributeModifier::String(StringMode::OneByte))\n      } else {\n        return Err(AttributeError::InvalidAttribute(syn::Error::new(\n          attr.span(),\n          \"invalid attribute for `string` modifier\",\n        )));\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\" {","sourceCodeStart":1373,"sourceCodeEnd":1409,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/libs/ops/op2/signature.rs#L1373-L1409","documentation":"The `string` modifier on op2 parameters accepts exactly two forms: bare `#[string]` (default mode) or `#[string(onebyte)]`. The parser in libs/ops/op2/signature.rs first checks for the bare `Meta::Path` form, then tries `parse_args::<Ident>` equal to `onebyte`; anything else raises this error on the attribute span.","triggerScenarios":"`#[string(utf8)]`, `#[string(twobyte)]`, `#[string(\"onebyte\")]`, or `#[string(onebyte, extra)]` on an op parameter or return type.","commonSituations":"Assuming a general string-encoding modifier exists; misspelling `onebyte` (e.g. `oneByte`, `one_byte`); passing a string literal instead of the bare identifier.","solutions":["Use `#[string]` for normal UTF-8 conversion, or `#[string(onebyte)]` when you specifically need a one-byte v8 string.","Spell the argument exactly as the bare identifier `onebyte` — lowercase, no underscores, no quotes."],"exampleFix":"// before\n#[op2]\nfn op_read(#[string(one_byte)] path: String) -> String { /* ... */ }\n\n// after\n#[op2]\nfn op_read(#[string(onebyte)] path: String) -> String { /* ... */ }","handlingStrategy":"validation","validationCode":"// Compile-time: `cargo check`. The closed form is:\n//   #[string]            or    #[string(onebyte)]\n// — nothing else parses.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to bare `#[string]`; reach for `#[string(onebyte)]` only when profiling shows one-byte strings matter.","Write the argument as the bare lowercase identifier `onebyte` — no underscores, no quotes."],"tags":["op2","proc-macro","string-conversion","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"}