windmill-labs/windmill · error

Found duplicate {} method, for route at path: {}

Error message

Found duplicate {} method, for route at path: {}

What it means

generate_paths builds the OpenAPI 'paths' object by iterating registered routes. OpenAPI allows only one entry per (path, HTTP method) pair; when two HttpRoute entries define the same method for the same route path, the generator fails with 'Found duplicate {method} method, for route at path: {}'.

Source

Thrown at backend/windmill-api-openapi/src/lib.rs:381

                    request_type = if route_path.starts_with("/run/") {
                        RequestType::Async
                    } else if route_path.starts_with("/run_and_stream/") {
                        RequestType::SyncSse
                    } else {
                        RequestType::Sync
                    };

                    let methods = if request_type == RequestType::Async {
                        vec![Method::POST]
                    } else {
                        vec![Method::GET, Method::POST]
                    };

                    (methods, true)
                }
                Kind::HttpRoute(HttpRouteConfig { method }) => {
                    if path_object.get(&method.to_string()).is_some() {
                        return Err(anyhow!(
                            "Found duplicate {} method, for route at path: {}",
                            method,
                            path.route_path
                        )
                        .into());
                    }
                    request_type = path.request_type.unwrap_or(RequestType::Sync);
                    (vec![method.to_owned()], false)
                }
            };

            for method in methods {
                let mut method_map = IndexMap::new();

                if let Some(summary) = path.summary.as_ref().filter(|s| !s.is_empty()) {
                    method_map.insert("summary", Value::String(summary.to_owned()));
                }

View on GitHub (pinned to e474e8803c)

Solutions

  1. Remove or rename one of the duplicate route registrations so each (path, method) pair is unique
  2. Grep the router setup for the reported path and method and reconcile the handlers
  3. If routes belong to feature-flagged modules, ensure only one variant is registered per build

Example fix

// before
.get(list_workspaces).get(get_workspace) // same path, duplicate GET
// after
.get(get_workspace)
Defensive patterns

Strategy: try-catch

Validate before calling

// before generating the spec, detect duplicate (path, method) pairs
let mut seen = std::collections::HashSet::new();
for p in paths {
    if let Kind::HttpRoute(c) = &p.kind {
        assert!(seen.insert((p.route_path.clone(), c.method.to_string())),
            "duplicate route {} {}", c.method, p.route_path);
    }
}

Try / catch

match generate_paths(&paths, url) {
    Ok(p) => p,
    Err(e) if e.to_string().contains("Found duplicate") => {
        tracing::error!("duplicate route registration: {e:#}");
        std::collections::HashMap::new() // or abort startup
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Two router registrations map the same HTTP method+path (after :param -> {param} normalization) to different handlers, e.g. GET /workspaces/:w_id defined twice, and generate_openapi_document -> generate_paths runs.

Common situations: A route moved to a different path but the old registration left behind; copy-pasted route handlers; route conflicts revealed only when the spec is generated because the router itself matched one first.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/ffe9461c0737569d. Report an issue: GitHub.