DioxusLabs/dioxus · error · syn::Error

HTTP method specified both in macro and in attribute

Error message

HTTP method specified both in macro and in attribute

What it means

The route macros come in two flavors: method-specific wrappers (`#[get]`, `#[post]`, `#[put]`, `#[delete]`, `#[patch]` — see packages/fullstack-macro/src/lib.rs:150-171) that inject the method, and the generic `#[route]` that reads it from the attribute arguments. The compiler rejects a route where a method is supplied on both paths (lib.rs:727-733).

Source

Thrown at packages/fullstack-macro/src/lib.rs:731

        }

        // Disallow multiple query params if one is a catch-all
        if query_params.iter().any(|param| param.catch_all) && query_params.len() > 1 {
            return Err(syn::Error::new(
                Span::call_site(),
                "Cannot have multiple query parameters when one is a catch-all",
            ));
        }

        if let Some(options) = route.oapi_options.as_mut() {
            options.merge_with_fn(function)
        }

        let method = match (method_from_macro, route.method) {
            (Some(method), None) => method,
            (None, Some(method)) => method,
            (Some(_), Some(_)) => {
                return Err(syn::Error::new(
                    Span::call_site(),
                    "HTTP method specified both in macro and in attribute",
                ));
            }
            (None, None) => {
                return Err(syn::Error::new(
                    Span::call_site(),
                    "HTTP method not specified in macro or in attribute",
                ));
            }
        };

        Ok(Self {
            method,
            route_lit: route.route_lit,
            path_params: route.path_params,
            query_params,
            oapi_options: route.oapi_options,

View on GitHub (pinned to 393d190a80)

Solutions

  1. If you use a method-named macro, remove the method from the attribute: `#[post("/submit")]`.
  2. If you want the method in the attribute, switch to the generic macro: `#[route(POST, "/submit")]`.
  3. Re-check after verb changes that the method appears in exactly one of the two places.

Example fix

// before
#[get(POST, "/submit")]
async fn submit(form: Form<Data>) { ... }

// after
#[post("/submit")]
async fn submit(form: Form<Data>) { ... }
Defensive patterns

Strategy: validation

Validate before calling

# Fail when a method-named macro also carries a method token inside the parens
rg -n '#\[(get|post|put|delete|patch)\(\s*(GET|POST|PUT|DELETE|PATCH)\b' src/ && \
  { echo 'ERROR: method specified both in macro name and attribute'; exit 1; } || true

Prevention

When it happens

Trigger: `#[get(POST, "/submit")]` — the `get` wrapper supplies GET while the attribute also names POST; `#[post("/x", method = PUT)]`-style double specification; converting a `#[route(GET, ...)]` handler to `#[get(...)]` and forgetting to delete the method token inside the parens.

Common situations: Copy-paste between handlers using different macro styles; changing the HTTP verb by editing the inner method instead of the macro name; examples mixing the two styles.

Related errors


AI-assisted analysis of DioxusLabs/dioxus@393d190a80 (2026-08-16). Data as JSON: /api/errors/fd49c5a9a0299315. Report an issue: GitHub.