DioxusLabs/dioxus · error · syn::Error

unexpected field, expected one of (summary, description, id,

Error message

unexpected field, expected one of (summary, description, id, hidden, tags, security, responses, transform)

What it means

The OpenAPI options block inside `#[api_route(...)]` is parsed key by key; only summary, description, id, hidden, tags, security, responses and transform are recognized (packages/fullstack-macro/src/lib.rs:1264-1277). Any other identifier inside that block is rejected with this error listing the valid keys.

Source

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

            security: None,
            responses: None,
            transform: None,
        };

        while !input.is_empty() {
            let ident = input.parse::<Ident>()?;
            let _ = input.parse::<Token![:]>()?;
            match ident.to_string().as_str() {
                "summary" => this.summary = Some((ident, input.parse()?)),
                "description" => this.description = Some((ident, input.parse()?)),
                "id" => this.id = Some((ident, input.parse()?)),
                "hidden" => this.hidden = Some((ident, input.parse()?)),
                "tags" => this.tags = Some((ident, input.parse()?)),
                "security" => this.security = Some((ident, input.parse()?)),
                "responses" => this.responses = Some((ident, input.parse()?)),
                "transform" => this.transform = Some((ident, input.parse()?)),
                _ => {
                    return Err(syn::Error::new(
                        ident.span(),
                        "unexpected field, expected one of (summary, description, id, hidden, tags, security, responses, transform)",
                    ));
                }
            }
            let _ = input.parse::<Token![,]>().ok();
        }

        Ok(this)
    }
}

impl OapiOptions {
    fn merge_with_fn(&mut self, function: &ItemFn) {
        if self.description.is_none() {
            self.description = doc_iter(&function.attrs)
                .skip(2)
                .map(|item| item.value())

View on GitHub (pinned to 393d190a80)

Solutions

  1. Use one of the eight allowed keys: summary, description, id, hidden, tags, security, responses, transform.
  2. Map OpenAPI vocabulary to macro keys: `operation_id` -> `id`, `title` -> `summary`; describe request/response shapes via `responses` or `transform`.
  3. For advanced cases (custom parameters, request bodies), pass an aide `transform` closure that mutates the generated operation.

Example fix

// before
#[api_route(GET, "/pets", operation_id = "list_pets")]
async fn list_pets() -> Json<Vec<Pet>> { ... }

// after
#[api_route(GET, "/pets", id = "list_pets")]
async fn list_pets() -> Json<Vec<Pet>> { ... }
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = {"summary", "description", "id", "hidden", "tags", "security", "responses", "transform"}
# Fail on unknown keys inside the OpenAPI options section of an api_route attribute
import re, sys
for m in re.finditer(r'#\[api_route\([^)]*\)\]', open('src/api.rs').read()):
    for k in re.findall(r'(\w+)\s*=', m.group(0)):
        if k in ALLOWED:
            continue
        if k not in {"GET", "POST", "PUT", "DELETE", "PATCH"}:
            sys.exit(f'unknown api_route key {k!r}; allowed: {sorted(ALLOWED)}')

Prevention

When it happens

Trigger: Writing `#[api_route(GET, "/pets", operation_id = "list")]` (should be `id`); `title = "..."` instead of `summary`; `parameters = ...` or `request_body = ...` which this macro does not expose (params come from the function signature); misspelling a key like `respones`.

Common situations: Porting annotations from utoipa/aide attributes (`operation_id`, `request_body`, `parameters`) that never existed here; guessing key names from OpenAPI spec vocabulary instead of the macro's list; version upgrades that add/rename keys (check the current eight).

Related errors


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