{"record":{"id":"87a8e251a76a62da","repo":"OpenAPITools/openapi-generator","slug":"empty-method-name-operationid-not-allowed-87a8e2","errorCode":null,"errorMessage":"Empty method name (operationId) not allowed","messagePattern":"Empty method name \\(operationId\\) not allowed","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java","lineNumber":865,"sourceCode":"        if (ModelUtils.isComposedSchema(p)) {\n            return openAPIType;\n        } else if (typeMapping.containsKey(openAPIType)) {\n            type = typeMapping.get(openAPIType);\n            String typeWithoutGeneric = typeWithoutGeneric(type);\n            if (languageSpecificPrimitives.contains(typeWithoutGeneric)) {\n                return type;\n            }\n        } else {\n            type = openAPIType;\n        }\n        return toModelName(type);\n    }\n\n    @Override\n    public String toOperationId(String operationId) {\n        // throw exception if method name is empty\n        if (StringUtils.isEmpty(operationId)) {\n            throw new RuntimeException(\"Empty method name (operationId) not allowed\");\n        }\n\n        operationId = camelize(sanitizeName(operationId), LOWERCASE_FIRST_LETTER);\n        operationId = toSafeIdentifier(operationId);\n\n        return operationId;\n    }\n\n    public void setModelPropertyNaming(String naming) {\n        try {\n            modelPropertyNaming = MODEL_PROPERTY_NAMING_TYPE.valueOf(naming);\n        } catch (IllegalArgumentException e) {\n            String values = Stream.of(MODEL_PROPERTY_NAMING_TYPE.values())\n                    .map(value -> \"'\" + value.name() + \"'\")\n                    .collect(Collectors.joining(\", \"));\n\n            String msg = String.format(Locale.ROOT, \"Invalid model property naming '%s'. Must be one of %s.\", naming, values);\n            throw new IllegalArgumentException(msg);","sourceCodeStart":847,"sourceCodeEnd":883,"githubUrl":"https://github.com/OpenAPITools/openapi-generator/blob/fcec517be3cf5b7964296bcba25fbc97541484e7/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java#L847-L883","documentation":"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.","triggerScenarios":"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.","commonSituations":"Spec-as-code pipelines rendering operationId from possibly-empty data; collections converted from Postman/curl without ids; specs where ids were stripped for deduplication.","solutions":["Provide a unique non-empty operationId for every operation","Remove operationId: '' entries and add a summary so default naming from summary/path works","Lint the spec for empty operationIds before running the TypeScript generator"],"exampleFix":"# before\nget:\n  operationId: ''\n  responses: { '200': { description: ok } }\n\n# after\nget:\n  operationId: getUsers\n  responses: { '200': { description: ok } }","handlingStrategy":"validation","validationCode":"// JS: catch empty operationIds before TS generation\nfor (const [p, item] of Object.entries(spec.paths || {})) {\n  for (const [m, op] of Object.entries(item)) {\n    if (!op || !op.responses) continue;\n    if (!op.operationId && !(op.summary || '').match(/[a-z0-9]/i)) fail(`${m} ${p}: no id and no usable summary`);\n    if (op.operationId === '') fail(`${m} ${p}: empty operationId`);\n  }\n}","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Give every operation an explicit non-empty operationId","Add a Spectral custom rule for empty operationIds in CI","After converting specs from other formats, backfill missing ids before generating"],"tags":["typescript","operationid","openapi-spec"],"backgroundTag":"missing-operation-id","analyzedSha":"fcec517be3cf5b7964296bcba25fbc97541484e7","analyzedAt":"2026-08-22T11:13:11.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}