OpenAPITools/openapi-generator · error · RuntimeException

Empty method name (operationId) not allowed

Error message

Empty method name (operationId) not allowed

What it means

The Swift 5 generator derives the method name from operationId via sanitizeName plus camelization. If the result is an empty string — the operationId is missing, blank, or made only of characters that sanitization strips — the generator throws, because a Swift method declaration requires a valid identifier.

Source

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

    @Override
    public String toModelDocFilename(String name) {
        return toModelName(name);
    }

    @Override
    public String toApiDocFilename(String name) {
        return toApiName(name);
    }

    @Override
    public String toOperationId(String operationId) {
        operationId = camelize(sanitizeName(operationId), LOWERCASE_FIRST_LETTER);

        // Throw exception if method name is empty.
        // This should not happen but keep the check just in case
        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)) {
            String newOperationId = camelize(("call_" + operationId), LOWERCASE_FIRST_LETTER);
            LOGGER.warn("{} (reserved word) cannot be used as method name. Renamed to {}", operationId, newOperationId);
            return newOperationId;
        }

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

        return operationId;
    }

View on GitHub (pinned to fcec517be3)

Solutions

  1. Add an explicit, unique, alphanumeric operationId to the failing operation in the spec.
  2. If an operationId exists but contains only special characters, rename it to a normal identifier.
  3. Add a Spectral lint rule requiring operationId on every operation so this fails in CI before generation.

Example fix

# before
paths:
  /pets:
    get:
      summary: list pets   # no operationId

# after
paths:
  /pets:
    get:
      operationId: listPets
      summary: list pets
Defensive patterns

Strategy: validation

Validate before calling

// node: every operation must keep a non-empty, sanitizable operationId
const hasValidOperationId = (op) =>
  typeof op.operationId === 'string' && /[a-zA-Z0-9]/.test(op.operationId);
Object.entries(spec.paths).forEach(([p, item]) =>
  Object.entries(item).forEach(([m, op]) => {
    if (['get','put','post','delete','patch','head','options','trace'].includes(m) && !hasValidOperationId(op))
      throw new Error(`missing operationId at ${m.toUpperCase()} ${p}`);
  }));

Type guard

const isValidOperationId = (id: unknown): id is string =>
  typeof id === 'string' && /[a-zA-Z0-9]/.test(id);

Try / catch

// Java
try { new DefaultGenerator().opts(input).generate(); }
catch (RuntimeException e) {
    if (e.getMessage().contains("operationId")) { /* add ids to the spec, regenerate once */ }
}

Prevention

When it happens

Trigger: An operation in the spec has no operationId (and the derived default sanitizes to nothing), or an operationId consisting only of symbols/whitespace such as '///' or '-'.

Common situations: Large specs authored without operationId where a path/method combination produces an empty default; specs exported from converters or gateways that drop operationId for edge-case paths; copy-paste operations where the id was left as a placeholder like '___'.

Related errors


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