{"record":{"id":"875347d886421773","repo":"elastic/elasticsearch","slug":"failed-to-load-external-sources-config","errorCode":null,"errorMessage":"Failed to load {EXTERNAL_SOURCES_CONFIG}","messagePattern":"Failed to load (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseToolsPlugin.java","lineNumber":133,"sourceCode":"\n        project.getTasks().register(\"pruneChangelogs\", PruneChangelogsTask.class).configure(task -> {\n            task.setGroup(\"Documentation\");\n            task.setDescription(\"Removes changelog files that have been used in a previous release\");\n            task.setChangelogs(yamlFiles);\n        });\n\n        project.getTasks().named(\"precommit\").configure(task -> task.dependsOn(validateChangelogsTask));\n    }\n\n    private static List<BundleChangelogsTask.ExternalChangelogSource> loadExternalSources() {\n        try (InputStream is = ReleaseToolsPlugin.class.getClassLoader().getResourceAsStream(EXTERNAL_SOURCES_CONFIG)) {\n            if (is == null) {\n                return List.of();\n            }\n            ObjectMapper mapper = new ObjectMapper(new YAMLFactory());\n            return mapper.readValue(is, new TypeReference<>() {});\n        } catch (IOException e) {\n            throw new UncheckedIOException(\"Failed to load \" + EXTERNAL_SOURCES_CONFIG, e);\n        }\n    }\n}\n","sourceCodeStart":115,"sourceCodeEnd":137,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseToolsPlugin.java#L115-L137","documentation":"Wrapped as UncheckedIOException from ReleaseToolsPlugin.loadExternalSources() when the classpath resource named by EXTERNAL_SOURCES_CONFIG exists but cannot be read or parsed as YAML into List<ExternalChangelogSource>. A missing resource is NOT an error (returns List.of()); only an IOException during read/parse triggers this.","triggerScenarios":"The external-sources YAML config file is present on the plugin classpath but is malformed YAML, has a schema that does not match ExternalChangelogSource, or the stream throws IOException mid-read.","commonSituations":"Someone edits the bundled external changelog sources YAML and introduces a syntax error; the Jackson ObjectMapper / YAMLFactory version is upgraded and becomes stricter on a previously-tolerated construct; the resource is packaged but truncated.","solutions":["Open the resource named by EXTERNAL_SOURCES_CONFIG (search build-tools-internal src/main/resources) and validate it as well-formed YAML matching the ExternalChangelogSource shape.","Run the YAML through an external parser (e.g. python yaml.safe_load) to pinpoint the offending line, then fix it.","If the file is genuinely optional, confirm the resource is absent (which returns List.of()) rather than present-but-broken."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate the resource parses before the build runs\ntry (InputStream is = ReleaseToolsPlugin.class.getClassLoader().getResourceAsStream(EXTERNAL_SOURCES_CONFIG)) {\n    if (is != null) {\n        new ObjectMapper(new YAMLFactory()).readValue(is, new TypeReference<List<BundleChangelogsTask.ExternalChangelogSource>>() {});\n    }\n} catch (IOException e) {\n    throw new IllegalStateException(\"External sources config is malformed: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"try { loadExternalSources(); } catch (UncheckedIOException e) { log.error(\"Fix the YAML at {} on the classpath\", EXTERNAL_SOURCES_CONFIG); throw e; }","preventionTips":["Lint the external sources YAML in CI (yamllint or a parse smoke test) on every change.","Treat the config file as code: review it, do not edit it ad-hoc during a release."],"tags":["release-tooling","yaml","classpath-resource","config","gradle"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}