OpenAPITools/openapi-generator · error · RuntimeException

Empty method/operation name (operationId) not allowed

Error message

Empty method/operation name (operationId) not allowed

What it means

AbstractEiffelCodegen.toOperationId throws when the operation name reaching it is null or empty. Eiffel feature names are generated from operationId and cannot be empty, so the run aborts. Default operationId derivation normally fills blanks from path+method, so an explicitly empty value or a bypassing code path is required to hit this.

Source

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

    @Override
    public String getSchemaType(Schema p) {
        String schemaType = super.getSchemaType(p);
        String type = null;
        if (typeMapping.containsKey(schemaType)) {
            type = typeMapping.get(schemaType);
            if (languageSpecificPrimitives.contains(type))
                return (type);
        } else
            type = schemaType;
        return type;
    }

    @Override
    public String toOperationId(String operationId) {
        // throw exception if method name is empty
        if (StringUtils.isEmpty(operationId)) {
            throw new RuntimeException("Empty method/operation name (operationId) not allowed");
        }

        String sanitizedOperationId = camelize(sanitizeName(operationId), LOWERCASE_FIRST_LETTER);

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

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

        // method name from updateSomething to update_Something.
        sanitizedOperationId = unCamelize(sanitizedOperationId);

View on GitHub (pinned to fcec517be3)

Solutions

  1. Provide a unique non-empty operationId for every operation.
  2. Remove the empty operationId key so default path-based naming applies.
  3. Check any custom Eiffel generator override that could forward an empty string.

Example fix

# before:
paths:
  /things:
    post:
      operationId: ''
# after:
paths:
  /things:
    post:
      operationId: createThing
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: ""' where default derivation is bypassed, or a custom generator calling toOperationId directly with a blank id.

Common situations: Machine-converted specs that drop operationIds; hand-edited specs with blank ids; generator subclasses on AbstractEiffelCodegen that preprocess ids.

Related errors


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