{"record":{"id":"73b81b68995b2dfa","repo":"elastic/elasticsearch","slug":"no-signatures-were-added-to-task-use-properties","errorCode":null,"errorMessage":"No signatures were added to task; use properties 'signatures', 'bundledSignatures', 'signaturesURLs', and/or 'signaturesFiles' to define those!","messagePattern":"No signatures were added to task; use properties 'signatures', 'bundledSignatures', 'signaturesURLs', and/or 'signaturesFiles' to define those!","errorType":"validation","errorClass":"InvalidUserDataException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/CheckForbiddenApisTask.java","lineNumber":524,"sourceCode":"                        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                }\n                checker.run();\n                writeMarker(getParameters().getSuccessMarker().getAsFile().get());\n            } catch (ForbiddenApiException e) {\n                throw new VerificationException(\"Forbidden API verification failed\", e);\n            } catch (Exception e) {","sourceCodeStart":506,"sourceCodeEnd":542,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/CheckForbiddenApisTask.java#L506-L542","documentation":"Thrown after signature parsing when checker.hasNoSignatures() is true AND checker.noSignaturesFilesParsed() — meaning the task was configured with no signature sources at all (no 'signatures', 'bundledSignatures', 'signaturesURLs', or 'signaturesFiles'). The task refuses to run because a forbidden-apis check with zero rules would silently pass on everything, hiding violations.","triggerScenarios":"A CheckForbiddenApisTask registration where none of the four signature-supplying properties were set, or all were set to empty.","commonSituations":"Registering a forbidden-apis task as a placeholder and forgetting to add bundledSignatures; a refactor that removed the signatures block; copying a task config and dropping the bundledSignatures line.","solutions":["Add at least one signature source, most commonly bundledSignatures: task.bundledSignatures = ['jdk-system-out', 'jdk-unsafe'].","Or add signaturesFiles / signatures / signaturesURLs as appropriate.","If the task is intentionally a no-op, remove the task registration rather than leaving an empty one."],"exampleFix":"// before\ntasks.named('forbiddenApisMain', CheckForbiddenApisTask) {\n  // no signatures\n}\n\n// after\ntasks.named('forbiddenApisMain', CheckForbiddenApisTask) {\n  bundledSignatures = ['jdk-system-out', 'jdk-unsafe', 'jdk-deprecated']\n}","handlingStrategy":"validation","validationCode":"// Assert at configuration time that at least one signature source is set\nboolean hasAny = (bundledSignatures != null && !bundledSignatures.isEmpty())\n             || (signatures != null && !signatures.isEmpty())\n             || (signaturesFiles != null && !signaturesFiles.isEmpty())\n             || (signaturesURLs != null && !signaturesURLs.isEmpty());\nif (!hasAny) throw new InvalidUserDataException(\"forbidden-apis task needs at least one signature source\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set bundledSignatures when registering a forbidden-apis task.","Delete rather than empty-out an unused forbidden-apis task.","Review task registrations during refactor to confirm signature wiring survives."],"tags":["gradle","forbidden-apis","precommit","task-config","signatures"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}