{"record":{"id":"fdc97094713b109c","repo":"OpenAPITools/openapi-generator","slug":"empty-method-name-operationid-not-allowed-fdc970","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/AbstractPythonCodegen.java","lineNumber":368,"sourceCode":"        // obtain the name from parameterNameMapping directly if provided\n        if (parameterNameMapping.containsKey(name)) {\n            return parameterNameMapping.get(name);\n        }\n\n        // to avoid conflicts with 'callback' parameter for async call\n        if (\"callback\".equals(name)) {\n            return \"param_callback\";\n        }\n\n        // use variable-name normalization without model property mappings\n        return toVarNameWithoutNameMapping(name);\n    }\n\n    @Override\n    public String toOperationId(String operationId) {\n        // throw exception if method name is empty (should not occur as an auto-generated method name will be used)\n        if (StringUtils.isEmpty(operationId)) {\n            throw new RuntimeException(\"Empty method name (operationId) not allowed\");\n        }\n\n        // method name cannot use reserved keyword, e.g. return\n        if (isReservedWord(operationId)) {\n            LOGGER.warn(\"{} (reserved word) cannot be used as method name. Renamed to {}\", operationId, underscore(sanitizeName(\"call_\" + operationId)));\n            operationId = \"call_\" + operationId;\n        }\n\n        // operationId starts with a number\n        if (operationId.matches(\"^\\\\d.*\")) {\n            LOGGER.warn(\"{} (starting with a number) cannot be used as method name. Renamed to {}\", operationId, underscore(sanitizeName(\"call_\" + operationId)));\n            operationId = \"call_\" + operationId;\n        }\n\n        return underscore(sanitizeName(operationId));\n    }\n\n    @Override","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/OpenAPITools/openapi-generator/blob/fcec517be3cf5b7964296bcba25fbc97541484e7/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java#L350-L386","documentation":"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.","triggerScenarios":"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.","commonSituations":"Specs converted from Postman/other formats that blank operationIds; hand-edited specs; generator subclasses that manipulate ids before calling super.","solutions":["Provide a unique non-empty operationId for each operation.","Remove the empty operationId key so the default path-derived name is used.","Guard custom generator overrides against forwarding empty ids."],"exampleFix":"# before:\npaths:\n  /users:\n    get:\n      operationId: ''\n# after:\npaths:\n  /users:\n    get:\n      operationId: list_users","handlingStrategy":"validation","validationCode":"// Pre-flight: every operation must have a non-empty operationId\nOpenAPI api = new OpenAPIV3Parser().read(\"spec.yaml\");\napi.getPaths().forEach((path, item) -> item.readOperationsMap().forEach((method, op) -> {\n    String id = op.getOperationId();\n    if (id == null || id.trim().isEmpty())\n        throw new IllegalStateException(method + \" \" + path + \" has an empty operationId\");\n}));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer explicit operationIds in specs over derived defaults.","Remove 'operationId: \"\"' entries — omit the key so a path-based default is generated.","Add a spec-lint rule for operationId presence in CI before Python generation."],"tags":["openapi","operationid","python","code-generation"],"backgroundTag":"missing-operation-id","analyzedSha":"fcec517be3cf5b7964296bcba25fbc97541484e7","analyzedAt":"2026-08-22T11:13:11.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}