OpenAPITools/openapi-generator · error · RuntimeException

Empty method name (operationId) not allowed

Error message

Empty method name (operationId) not allowed

What it means

AbstractTypeScriptClientCodegen.toOperationId throws RuntimeException when the operationId is empty, before camelize/sanitizeName/toSafeIdentifier run. As with the other toOperationId guards, DefaultCodegen normally synthesizes an id (from the summary, else method+path) first, so this fires only when the incoming id is genuinely empty — an explicit empty operationId with nothing to synthesize from, or a direct API call.

Source

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

        if (ModelUtils.isComposedSchema(p)) {
            return openAPIType;
        } else if (typeMapping.containsKey(openAPIType)) {
            type = typeMapping.get(openAPIType);
            String typeWithoutGeneric = typeWithoutGeneric(type);
            if (languageSpecificPrimitives.contains(typeWithoutGeneric)) {
                return type;
            }
        } else {
            type = openAPIType;
        }
        return toModelName(type);
    }

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

        operationId = camelize(sanitizeName(operationId), LOWERCASE_FIRST_LETTER);
        operationId = toSafeIdentifier(operationId);

        return operationId;
    }

    public void setModelPropertyNaming(String naming) {
        try {
            modelPropertyNaming = MODEL_PROPERTY_NAMING_TYPE.valueOf(naming);
        } catch (IllegalArgumentException e) {
            String values = Stream.of(MODEL_PROPERTY_NAMING_TYPE.values())
                    .map(value -> "'" + value.name() + "'")
                    .collect(Collectors.joining(", "));

            String msg = String.format(Locale.ROOT, "Invalid model property naming '%s'. Must be one of %s.", naming, values);
            throw new IllegalArgumentException(msg);

View on GitHub (pinned to fcec517be3)

Solutions

  1. Provide a unique non-empty operationId for every operation
  2. Remove operationId: '' entries and add a summary so default naming from summary/path works
  3. Lint the spec for empty operationIds before running the TypeScript generator

Example fix

# before
get:
  operationId: ''
  responses: { '200': { description: ok } }

# after
get:
  operationId: getUsers
  responses: { '200': { description: ok } }
Defensive patterns

Strategy: validation

Validate before calling

// JS: catch empty operationIds before TS generation
for (const [p, item] of Object.entries(spec.paths || {})) {
  for (const [m, op] of Object.entries(item)) {
    if (!op || !op.responses) continue;
    if (!op.operationId && !(op.summary || '').match(/[a-z0-9]/i)) fail(`${m} ${p}: no id and no usable summary`);
    if (op.operationId === '') fail(`${m} ${p}: empty operationId`);
  }
}

Try / catch

try { generator.generate(); } catch (RuntimeException e) { if ("Empty method name (operationId) not allowed".equals(e.getMessage())) { /* add an operationId to the failing operation */ } throw e; }

Prevention

When it happens

Trigger: An operation defined as { get: { operationId: '', responses: ... } } with no summary (or a summary that sanitizes to empty), or programmatic generator use passing ''. Distinct from invalid ids: reserved words and digit-leading ids are sanitized (toSafeIdentifier / camelize), not rejected.

Common situations: Spec-as-code pipelines rendering operationId from possibly-empty data; collections converted from Postman/curl without ids; specs where ids were stripped for deduplication.

Related errors


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