OpenAPITools/openapi-generator · error · RuntimeException

Empty method name (operationId) not allowed

Error message

Empty method name (operationId) not allowed

What it means

AbstractPythonCodegen.toOperationId throws when the operation name reaching it is null or empty. Python generated API methods use operationId as the method name; an empty one would emit invalid Python, so generation aborts. The code comment notes it should not occur normally because an auto-generated name is used, so it points to an explicit blank value or a bypassing custom path.

Source

Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java:368

        // obtain the name from parameterNameMapping directly if provided
        if (parameterNameMapping.containsKey(name)) {
            return parameterNameMapping.get(name);
        }

        // to avoid conflicts with 'callback' parameter for async call
        if ("callback".equals(name)) {
            return "param_callback";
        }

        // use variable-name normalization without model property mappings
        return toVarNameWithoutNameMapping(name);
    }

    @Override
    public String toOperationId(String operationId) {
        // throw exception if method name is empty (should not occur as an auto-generated method name will be used)
        if (StringUtils.isEmpty(operationId)) {
            throw new RuntimeException("Empty method name (operationId) not allowed");
        }

        // method name cannot use reserved keyword, e.g. return
        if (isReservedWord(operationId)) {
            LOGGER.warn("{} (reserved word) cannot be used as method name. Renamed to {}", operationId, underscore(sanitizeName("call_" + operationId)));
            operationId = "call_" + operationId;
        }

        // operationId starts with a number
        if (operationId.matches("^\\d.*")) {
            LOGGER.warn("{} (starting with a number) cannot be used as method name. Renamed to {}", operationId, underscore(sanitizeName("call_" + operationId)));
            operationId = "call_" + operationId;
        }

        return underscore(sanitizeName(operationId));
    }

    @Override

View on GitHub (pinned to fcec517be3)

Solutions

  1. Provide a unique non-empty operationId for each operation.
  2. Remove the empty operationId key so the default path-derived name is used.
  3. Guard custom generator overrides against forwarding empty ids.

Example fix

# before:
paths:
  /users:
    get:
      operationId: ''
# after:
paths:
  /users:
    get:
      operationId: list_users
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: every operation must have a non-empty operationId
OpenAPI api = new OpenAPIV3Parser().read("spec.yaml");
api.getPaths().forEach((path, item) -> item.readOperationsMap().forEach((method, op) -> {
    String id = op.getOperationId();
    if (id == null || id.trim().isEmpty())
        throw new IllegalStateException(method + " " + path + " has an empty operationId");
}));

Prevention

When it happens

Trigger: A spec operation with 'operationId: ""' processed through a path that skips default derivation, or a custom Python generator calling toOperationId directly with an empty id.

Common situations: Specs converted from Postman/other formats that blank operationIds; hand-edited specs; generator subclasses that manipulate ids before calling super.

Related errors


AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22). Data as JSON: /api/errors/fdc97094713b109c. Report an issue: GitHub.