{"record":{"id":"4a88d4a49f34bafc","repo":"elastic/elasticsearch","slug":"can-t-find-revision-for-refname-refname","errorCode":null,"errorMessage":"Can't find revision for refName ${refName}","messagePattern":"Can't find revision for refName (.+?)","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/info/GitInfo.java","lineNumber":125,"sourceCode":"                } else if (Files.exists(gitDir.resolve(\"packed-refs\"))) {\n                    // Check packed references for commit ID\n                    Pattern p = Pattern.compile(\"^([a-f0-9]{40}) \" + refName + \"$\");\n                    try (Stream<String> lines = Files.lines(gitDir.resolve(\"packed-refs\"))) {\n                        revision = lines.map(p::matcher)\n                                .filter(Matcher::matches)\n                                .map(m -> m.group(1))\n                                .findFirst()\n                                .orElseThrow(() -> new IOException(\"Packed reference not found for refName \" + refName));\n                    }\n                } else {\n                    File refsDir = gitDir.resolve(\"refs\").toFile();\n                    if (refsDir.exists()) {\n                        String foundRefs = Arrays.stream(refsDir.listFiles()).map(f -> f.getName()).collect(Collectors.joining(\"\\n\"));\n                        Logging.getLogger(GitInfo.class).error(\"Found git refs\\n\" + foundRefs);\n                    } else {\n                        Logging.getLogger(GitInfo.class).error(\"No git refs dir found\");\n                    }\n                    throw new GradleException(\"Can't find revision for refName \" + refName);\n                }\n            } else {\n                // we are in detached HEAD state\n                revision = ref;\n            }\n            return new GitInfo(revision, findOriginUrl(gitDir.resolve(\"config\")));\n        } catch (final IOException e) {\n            // for now, do not be lenient until we have better understanding of real-world scenarios where this happens\n            throw new GradleException(\"unable to read the git revision\", e);\n        }\n    }\n\n\n    private static String findOriginUrl(final Path configFile) throws IOException {\n        Map<String, String> props = new HashMap<>();\n\n        try (Stream<String> stream = Files.lines(configFile, StandardCharsets.UTF_8)) {\n            Iterator<String> lines = stream.iterator();","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/info/GitInfo.java#L107-L143","documentation":"GitInfo.gitInfo reads the .git metadata directly instead of forking git. When HEAD points at a ref (e.g. refs/heads/main) but neither a loose ref file at that path nor a matching entry in packed-refs exists, the revision cannot be resolved and this GradleException is thrown. The error log just above lists whatever refs were found (or reports no refs dir) to aid diagnosis.","triggerScenarios":"HEAD contains `ref: refs/heads/<branch>` but the loose ref file is absent AND packed-refs is either missing or lacks the matching line. This happens in a broken worktree, a corrupted repo, or an exotic git layout the manual parser does not handle.","commonSituations":"A corrupted .git after an interrupted operation; a manually constructed git directory without packed-refs; a CI image built from a tarball that dropped loose refs; switching branches while the refstore is being rewritten; very old git clients producing layouts the parser does not expect.","solutions":["Re-clone the repository to get a clean .git directory.","Run `git fsck --full` and `git pack-refs --all` to repair and consolidate refs, then retry.","Check the logged `Found git refs` / `No git refs dir found` message to see what the parser actually saw.","If reproducible only in a specific worktree, recreate the worktree with `git worktree add`."],"exampleFix":"// before: HEAD points at refs/heads/main but no loose/packed ref exists\n// repair the refstore\ngit fsck --full && git pack-refs --all","handlingStrategy":"fallback","validationCode":"// Before relying on GitInfo.gitInfo, sanity-check the refstore\nPath dotGit = rootDir.toPath().resolve(\".git\");\nPath head = Files.isDirectory(dotGit) ? dotGit.resolve(\"HEAD\") : dotGit;\nString ref = Files.readString(head).trim();\nif (ref.startsWith(\"ref:\")) {\n    String refName = ref.substring(\"ref:\".length()).trim();\n    Path loose = dotGit.resolve(refName);\n    Path packed = dotGit.resolve(\"packed-refs\");\n    if (!Files.exists(loose) && (!Files.exists(packed) || Files.readString(packed).lines().noneMatch(l -> l.endsWith(\" \" + refName)))) {\n        getLogger().warn(\"Git ref {} cannot be resolved locally; run git fsck\", refName);\n    }\n}","typeGuard":null,"tryCatchPattern":"// GitInfo is called by build internals; if you invoke it directly, degrade gracefully\ntry {\n    GitInfo info = GitInfo.gitInfo(rootDir);\n} catch (GradleException e) {\n    if (e.getMessage().contains(\"Can't find revision\")) {\n        getLogger().warn(\"Git ref missing; using 'unknown' revision\");\n        info = new GitInfo(\"unknown\", \"unknown\"); // constructor is private; use a fallback property instead\n    } else { throw e; }\n}","preventionTips":["Build only from healthy, freshly-cloned repositories.","Run `git fsck --full` in CI before the build to catch refstore corruption.","Avoid manually editing .git internals."],"tags":["gradle","git","metadata","build-info"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}