{"record":{"id":"4a11caf491b0c578","repo":"elastic/elasticsearch","slug":"parsing-signatures-failed","errorCode":null,"errorMessage":"Parsing signatures failed: {}","messagePattern":"Parsing signatures failed: (.+?)","errorType":"validation","errorClass":"InvalidUserDataException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/CheckForbiddenApisTask.java","lineNumber":519,"sourceCode":"                        }\n                    }\n\n                    final FileCollection signaturesFiles = getParameters().getSignaturesFiles();\n                    if (signaturesFiles != null) for (final File f : signaturesFiles) {\n                        checker.parseSignaturesFile(f);\n                    }\n                    final List<String> signatures = getParameters().getSignatures().get();\n                    if ((signatures != null) && !signatures.isEmpty()) {\n                        final StringBuilder sb = new StringBuilder();\n                        for (String line : signatures) {\n                            sb.append(line).append(NL);\n                        }\n                        checker.parseSignaturesString(sb.toString());\n                    }\n                } catch (IOException ioe) {\n                    throw new GradleException(\"IO problem while reading files with API signatures.\", ioe);\n                } catch (ParseException pe) {\n                    throw new InvalidUserDataException(\"Parsing signatures failed: \" + pe.getMessage(), pe);\n                }\n\n                if (checker.hasNoSignatures()) {\n                    if (checker.noSignaturesFilesParsed()) {\n                        throw new InvalidUserDataException(\n                            \"No signatures were added to task; use properties 'signatures', 'bundledSignatures', 'signaturesURLs', and/or 'signaturesFiles' to define those!\"\n                        );\n                    } else {\n                        logger.info(\"Skipping execution because no API signatures are available.\");\n                        return;\n                    }\n                }\n\n                try {\n                    checker.addClassesToCheck(getParameters().getClassFiles());\n                } catch (IOException ioe) {\n                    throw new GradleException(\"Failed to load one of the given class files.\", ioe);\n                }","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/CheckForbiddenApisTask.java#L501-L537","documentation":"Thrown when the forbidden-apis checker raises a ParseException while parsing a signatures file or the joined inline signatures string. The signature syntax is invalid (malformed method/field signature), so the checker cannot build its rule set. This is a user-data error in the signature definition, distinct from [243] which is an IO fault.","triggerScenarios":"A signature line that does not match the forbidden-apis signature grammar (e.g. missing class@method form, wrong descriptor syntax, unparseable type), supplied via the 'signatures' property or a signatures file.","commonSituations":"Hand-written signature files with typos; copying a signature from a different forbidden-apis version with incompatible grammar; an inline signatures string with stray characters; upgrading the forbidden-apis dependency which changed signature syntax.","solutions":["Read pe.getMessage() in the stack trace — it names the offending signature and the parse position.","Open the cited signatures file/line and correct the signature to the form ClassName#methodName(descriptor) or ClassName#fieldName.","Validate against the forbidden-apis documentation for the bundled version.","Re-run the single task to confirm parsing succeeds."],"exampleFix":"// before (broken)\njava.lang.String#substring(int,int) typo\n\n// after\njava.lang.String#substring(int,int)","handlingStrategy":"validation","validationCode":"// Lint signature lines against the forbidden-apis grammar before passing them\nfor (String line : signatures) {\n    String s = line.trim();\n    if (s.isEmpty() || s.startsWith(\"#\") || s.startsWith(\"@\")) continue;\n    if (!s.matches(\"[\\\\w.$]+(#\\\\w+(\\\\([^)]*\\))?|#\\\\w+|\\\\s+.*).*\")) {\n        throw new InvalidUserDataException(\"Malformed signature: \" + s);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    checker.parseSignaturesString(joined);\n} catch (InvalidUserDataException e) {\n    // e.getCause() is the ParseException; its message names the bad token\n    throw e;\n}","preventionTips":["Validate signature syntax in CI by running the forbidden-apis task on every PR.","Copy signature grammar from the bundled version's docs.","Comment every non-obvious signature so reviewers catch typos."],"tags":["gradle","forbidden-apis","precommit","signatures","parse-error"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}