denoland/deno · error · syn::Error

Only ASCII keys are supported

Error message

Only ASCII keys are supported

What it means

deno_core's op/webidl macros build object keys with `v8::String::new_from_one_byte`, which only accepts one-byte (Latin-1) input. `get_internalized_string` in libs/ops/lib.rs therefore rejects any identifier used as a JS property key (op struct fields, webidl dictionary fields, enum tags, including camelCased js_names derived from field names) that contains non-ASCII characters.

Source

Thrown at libs/ops/lib.rs:67

    Err(err) => err.into_compile_error().into(),
  }
}

#[proc_macro_derive(ToV8, attributes(to_v8, v8))]
pub fn to_v8(item: TokenStream) -> TokenStream {
  match conversion::to_v8::to_v8(item.into()) {
    Ok(output) => output.into(),
    Err(err) => err.into_compile_error().into(),
  }
}

fn get_internalized_string(
  name: syn::Ident,
) -> Result<proc_macro2::TokenStream, syn::Error> {
  let name_str = name.to_string();

  if !name_str.is_ascii() {
    return Err(syn::Error::new(
      name.span(),
      "Only ASCII keys are supported",
    ));
  }

  Ok(quote::quote! {
    ::deno_core::v8::String::new_from_one_byte(
      __scope,
      #name_str.as_bytes(),
      ::deno_core::v8::NewStringType::Internalized,
    )
    .unwrap()
    .into()
  })
}

#[cfg(test)]
mod infra {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Rename the Rust field/variant to an ASCII identifier; if the JS property name must stay non-ASCII, that is not supported by these macros at all.
  2. Keep `non_ascii_idents` disabled in the crate so the compiler itself blocks such identifiers early.
  3. If you only need a different ASCII JS name, use the rename mechanism (e.g. `#[webidl(rename = "...")]` with an ASCII value) instead of a non-ASCII Rust identifier.

Example fix

// before (nightly non_ascii_idents)
#[derive(WebIDL)]
#[webidl(dictionary)]
struct FontOptions { pub fett: bool }
// ...a field named `größe` fails: "Only ASCII keys are supported"

// after
#[derive(WebIDL)]
#[webidl(dictionary)]
struct FontOptions { pub gross: bool }
Defensive patterns

Strategy: validation

Validate before calling

// Keep the crate on stable Rust (no `non_ascii_idents` feature); stable rejects
// non-ASCII identifiers before the macro ever runs:
// [lib] ... (do NOT enable) #![feature(non_ascii_idents)]
// Optional CI guard:
// ! grep -rnP '[^\x00-\x7F]' --include='*.rs' src/ | grep -E 'fn |struct |enum ' && exit 1

Prevention

When it happens

Trigger: Naming a field of a struct used in `#[serde]`-style to_v8/from_v8 conversion, a webidl dictionary field, or an enum variant/tag with non-ASCII characters (accents, CJK, Cyrillic). Rust itself permits non-ASCII identifiers on nightly (`#![feature(non_ascii_idents)]`), but the macro rejects them because `#name_str.is_ascii()` fails.

Common situations: Writing bindings for an API whose domain model uses accented identifiers (e.g. `café`, `größe`) and mirroring those names into Rust structs passed to op2/webidl macros; enabling `non_ascii_idents` crate-wide and forgetting this macro restriction.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/f3d1a1a400971067. Report an issue: GitHub.