midudev/autoskills · error · Error
could not resolve HEAD for
Error message
could not resolve HEAD for ${repo} What it means
After a successful `git ls-remote`, resolveRepoHead parses the output lines for a `<40-hex-sha> HEAD` entry to learn the repo's default branch and commit SHA. If no such line is found (sha stays empty), it throws this error. It means the remote answered but its HEAD symref could not be resolved to a commit.
Solutions
- Confirm the repo is not empty (has at least one commit on its default branch)
- Run `git ls-remote <url> HEAD` manually and check that a SHA line is printed
- Ensure the remote advertises HEAD symrefs (use GitHub or update the hosting/proxy)
- Fall back to pinning an explicit branch/SHA instead of relying on HEAD resolution
Example fix
// before
const head = await resolveRepoHead("org/empty-repo"); // throws
// after
const head = await resolveRepoHead("org/skills-repo"); // non-empty repo Defensive patterns
Strategy: validation
Validate before calling
// verify the repo advertises a resolvable HEAD
const out = execSync(`git ls-remote https://github.com/${repo} HEAD`, { encoding: "utf8" });
if (!/^[0-9a-f]{40}\s+HEAD$/im.test(out)) {
throw new Error(`${repo} has no resolvable HEAD (empty repo?)`);
} Try / catch
try {
const head = await resolveRepoHead(repo);
} catch (err) {
if (err.message.startsWith("could not resolve HEAD")) {
console.error(`Repo ${repo} appears empty or HEAD is not advertised`);
// skip repo or fall back to a pinned branch/sha
} else throw err;
} Prevention
- Only sync non-empty repos with at least one commit
- Prefer GitHub-hosted repos, which always advertise HEAD symrefs
- Pin an explicit branch/SHA when HEAD resolution is unreliable
- Check ls-remote output manually for unusual git hosts
When it happens
Trigger: `git ls-remote` output contains no line matching /^([0-9a-f]{40})\s+HEAD$/i — e.g. the remote returns no HEAD entry, output format is unexpected, or the ls-remote invocation didn't include the HEAD ref (odd server configs, empty repos with no commits).
Common situations: Syncing an initialized but completely empty GitHub repo; a git server/proxy that mangles or omits the HEAD symref line; very old or unusual git hosting that doesn't advertise HEAD in ls-remote output.
Related errors
- git ls-remote failed for
- git tree truncated for
- failed
- ⚠️ No se pudo eliminar el tag v
- ⚠️ No se pudo revertir el commit de release automáticamente
AI-assisted analysis of midudev/autoskills@0ec725320d (2026-09-15).
Data as JSON: /api/errors/6807d0bebf298ad7.
Report an issue: GitHub.
Appendix: source
Thrown at packages/autoskills/scripts/sync-skills.mjs:192
);
if (result.status !== 0) {
throw new Error(`git ls-remote failed for ${repo}: ${result.stderr.trim() || "unknown error"}`);
}
let defaultBranch = "main";
let sha = "";
for (const line of result.stdout.split("\n")) {
const symref = line.match(/^ref:\s+refs\/heads\/(.+)\s+HEAD$/);
if (symref) {
defaultBranch = symref[1];
continue;
}
const head = line.match(/^([0-9a-f]{40})\s+HEAD$/i);
if (head) sha = head[1];
}
if (!sha) {
throw new Error(`could not resolve HEAD for ${repo}`);
}
return { defaultBranch, sha };
}
async function resolveRepoInfo(repo) {
const res = await ghFetch(`https://api.github.com/repos/${repo}`);
const body = await res.json();
return {
sizeKB: body.size || 0,
};
}
// Tarball download size threshold (KB). Above this we use per-file fetch.
const HEAVY_REPO_KB = 50_000;
// Hard timeout for tarball downloads. Some repos have slow codeload CDNs.
const TARBALL_TIMEOUT_MS = 180_000;
View on GitHub (pinned to 0ec725320d)