{"record":{"id":"231063999aa4eaf4","repo":"OpenAPITools/openapi-generator","slug":"empty-method-name-operationid-not-allowed-231063","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/XojoClientCodegen.java","lineNumber":429,"sourceCode":"            if (sec.isApiKey) sec.name = toVarName(sec.name);\n        }\n\n        return securities;\n    }\n\n    @Override\n    public GeneratorLanguage generatorLanguage() {\n        return GeneratorLanguage.XOJO;\n    }\n\n    @Override\n    public String toOperationId(String operationId) {\n        operationId = camelize(sanitizeName(operationId));\n\n        // Throw exception if method name is empty.\n        // This should not happen but keep the check just in case\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            String newOperationId = camelize((\"Call_\" + operationId));\n            LOGGER.warn(\"{} (reserved word) cannot be used as method name. Renamed to {}\", operationId, newOperationId);\n            return newOperationId;\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, camelize(sanitizeName(\"call_\" + operationId), LOWERCASE_FIRST_LETTER));\n            operationId = camelize(sanitizeName(\"Call_\" + operationId));\n        }\n\n        return operationId;\n    }\n","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/OpenAPITools/openapi-generator/blob/fcec517be3cf5b7964296bcba25fbc97541484e7/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/XojoClientCodegen.java#L411-L447","documentation":"XojoClientCodegen.toOperationId (line 429) camelize+sanitizeName's the operationId and then refuses an empty result. This happens when the spec's operationId (or the derived name) consists entirely of characters that sanitizeName strips, leaving nothing to build a Xojo method name from. The check is defensive — normal specs never hit it — but a RuntimeException is thrown because generation cannot continue without a method name.","triggerScenarios":"An OpenAPI operation with operationId: \"###\" or \"///\" (only special characters), or a missing operationId on a path whose auto-derived name sanitizes to empty. Only the Xojo generator path shown throws here, but any spec with such an operation is the root cause.","commonSituations":"Hand-edited specs where operationId was deleted instead of renamed; codegen'd specs from tools that emit symbol-only identifiers; specs with non-ASCII operationIds that sanitization strips to nothing.","solutions":["Open the spec and give every operation (paths -> verbs) a non-empty operationId containing at least one letter or digit (e.g. 'getUser').","If operationIds look fine, check for operationIds made only of punctuation/whitespace or duplicated special characters after sanitization.","Validate the spec with a linter (Swagger Editor / spectral) before generation to catch malformed identifiers."],"exampleFix":"# before (openapi.yaml)\npaths:\n  /users:\n    get:\n      operationId: \"###\"\n\n# after\npaths:\n  /users:\n    get:\n      operationId: getUser","handlingStrategy":"validation","validationCode":"// Node: reject operations whose operationId sanitizes to empty before generating\nconst spec = require('./openapi.json');\nfor (const [path, item] of Object.entries(spec.paths ?? {}))\n  for (const [verb, op] of Object.entries(item))\n    if (/^(get|put|post|delete|options|head|patch|trace)$/.test(verb)) {\n      const id = (op.operationId ?? '').replace(/[^a-zA-Z0-9]/g, '');\n      if (id.length === 0) throw new Error(`${verb.toUpperCase()} ${path}: empty/invalid operationId`);\n    }","typeGuard":null,"tryCatchPattern":"catch (RuntimeException e) {\n    // message names the offending operation path — fix the spec and regenerate\n    if (e.getMessage().contains(\"Empty method name (operationId) not allowed\")) {\n        throw new SpecError(\"An operationId sanitized to empty; add a valid operationId to every operation\", e);\n    }\n    throw e;\n}","preventionTips":["Give every operation an explicit, unique operationId — never rely on derivation.","Run spectral/Swagger Editor validation in CI to catch malformed identifiers early.","Avoid operationIds made solely of punctuation, whitespace or symbols."],"tags":["xojo","openapi","operationid","codegen","spec-validation"],"backgroundTag":"missing-operationid","analyzedSha":"fcec517be3cf5b7964296bcba25fbc97541484e7","analyzedAt":"2026-08-22T11:13:11.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}