tauri-apps/tauri · error · syn::Error

expected string literal for rename

Error message

expected string literal for rename

What it means

The rename key of #[tauri::command] overrides the exposed name of a single command and must be a plain string literal, because the macro splices the literal into generated code. The parser explicitly checks for Expr::Lit with Lit::Str; any other expression (number, const, macro call) is rejected with the span on the whole name=value pair.

Source

Thrown at crates/tauri-macros/src/command/wrapper.rs:87

                "snake_case" => ArgumentCase::Snake,
                "camelCase" => ArgumentCase::Camel,
                _ => {
                  return Err(syn::Error::new(
                    s.span(),
                    "expected \"camelCase\" or \"snake_case\"",
                  ))
                }
              };
            }
          } else if v.path.is_ident("rename") {
            if let Expr::Lit(ExprLit {
              lit: Lit::Str(s), ..
            }) = v.value
            {
              let lit = s.value();
              wrapper_attributes.rename = RenamePolicy::Rename(quote!(#lit));
            } else {
              return Err(syn::Error::new(
                v.span(),
                "expected string literal for rename",
              ));
            }
          } else if v.path.is_ident("root") {
            if let Expr::Lit(ExprLit {
              lit: Lit::Str(s),
              attrs: _,
            }) = v.value
            {
              let lit = s.value();

              wrapper_attributes.root = if lit == "crate" {
                quote!($crate)
              } else {
                let ident = Ident::new(&lit, Span::call_site());
                quote!(#ident)
              };

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Pass a plain string literal: #[tauri::command(rename = "myCustomName")]
  2. If you need a computed name, wrap the command in a generated module via a small local macro that interpolates the literal
  3. Double-check you used rename (single command name) and not rename_all (argument casing)

Example fix

// before
const API_NAME: &str = "fetchItems";
#[tauri::command(rename = API_NAME)]
fn fetch_items() {}
// after
#[tauri::command(rename = "fetchItems")]
fn fetch_items() {}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: #[tauri::command(rename = 5)], #[tauri::command(rename = MY_CONST)], or #[tauri::command(rename = concat!("api", "_thing"))].

Common situations: Trying to build the command name from consts or macros to avoid repetition; unquoting mistakes when copying from template strings; JSON-style thinking where rename values arrive from elsewhere.

Related errors


AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20). Data as JSON: /api/errors/f971c426a1fd5953. Report an issue: GitHub.