{"record":{"id":"b7b52d44b83b438e","repo":"elastic/elasticsearch","slug":"failed-to-read-as-utf-8","errorCode":null,"errorMessage":"Failed to read {} as UTF_8","messagePattern":"Failed to read (.+?) as UTF_8","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ForbiddenPatternsTask.java","lineNumber":125,"sourceCode":"    public FileCollection getFiles() {\n        return getSourceFolders().get()\n            .stream()\n            .map(sourceFolder -> sourceFolder.matching(filesFilter))\n            .reduce(FileTree::plus)\n            .orElse(projectLayout.files().getAsFileTree());\n    }\n\n    @TaskAction\n    public void checkInvalidPatterns() throws IOException {\n        Pattern allPatterns = Pattern.compile(\"(\" + String.join(\")|(\", getPatterns().values()) + \")\");\n        List<Problem> problems = new ArrayList<>();\n        List<String> violations = new ArrayList<>();\n        for (File f : getFiles()) {\n            List<String> lines;\n            try (Stream<String> stream = Files.lines(f.toPath(), StandardCharsets.UTF_8)) {\n                lines = stream.collect(Collectors.toList());\n            } catch (UncheckedIOException e) {\n                throw new IllegalArgumentException(\"Failed to read \" + f + \" as UTF_8\", e);\n            }\n\n            URI baseUri = getRootDir().orElse(projectLayout.getProjectDirectory().getAsFile()).get().toURI();\n            String path = baseUri.relativize(f.toURI()).toString();\n            String absolutePath = f.getAbsolutePath();\n            IntStream.range(0, lines.size())\n                .filter(i -> allPatterns.matcher(lines.get(i)).find())\n                .mapToObj(l -> new AbstractMap.SimpleEntry<>(l + 1, lines.get(l)))\n                .forEach(\n                    kv -> patterns.entrySet()\n                        .stream()\n                        .filter(p -> Pattern.compile(p.getValue()).matcher(kv.getValue()).find())\n                        .forEach(p -> {\n                            int lineNumber = kv.getKey();\n                            String ruleName = p.getKey();\n                            String label = ruleName + \" on line \" + lineNumber + \" of \" + path;\n                            violations.add(\"- \" + label);\n                            problems.add(","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ForbiddenPatternsTask.java#L107-L143","documentation":"Thrown by ForbiddenPatternsTask.checkInvalidPatterns when Files.lines on a source file raises UncheckedIOException (wrapping an IOException). The task reads every checked file as UTF-8 to scan for forbidden patterns; a file that cannot be read/decoded aborts the scan with this IllegalArgumentException.","triggerScenarios":"A file in getFiles() that does not exist at read time, is not readable, or contains bytes that break the UTF-8 decoder under Files.lines.","commonSituations":"A source file deleted between configuration and execution; a file containing non-UTF-8 bytes (legacy Latin-1); a file on a network mount that became unreachable; permission issues.","solutions":["Open the wrapped UncheckedIOException to find the failing file and root cause.","If the file is non-UTF-8, convert it to UTF-8 (iconv -f LATIN1 -t UTF-8 file) or add it to the task's exclude filter.","If the file was deleted mid-build, ensure sources are stable before the task runs (proper task dependencies).","Fix filesystem permissions / remount if the cause is I/O."],"exampleFix":"# before: file is Latin-1 encoded\n# after\niconv -f LATIN1 -t UTF-8 src/main/resources/legacy.txt -o src/main/resources/legacy.txt","handlingStrategy":"validation","validationCode":"// Confirm files are readable UTF-8 before scanning\nfor (File f : getFiles()) {\n    if (!f.isFile()) throw new IllegalArgumentException(\"Missing file: \" + f);\n    try { Files.readString(f.toPath(), StandardCharsets.UTF_8); }\n    catch (IOException e) { throw new IllegalArgumentException(\"Not UTF-8 / unreadable: \" + f, e); }\n}","typeGuard":null,"tryCatchPattern":"try (Stream<String> s = Files.lines(f.toPath(), StandardCharsets.UTF_8)) {\n    ...\n} catch (IllegalArgumentException e) {\n    if (e.getCause() instanceof UncheckedIOException) {\n        // convert the file to UTF-8 or exclude it, then re-run\n    }\n    throw e;\n}","preventionTips":["Keep all source/resource files UTF-8.","Add an editorconfig with charset = utf-8 and enforce in CI.","Exclude generated/binary files from ForbiddenPatternsTask sources."],"tags":["gradle","forbidden-patterns","precommit","encoding","io"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}