santifer/career-ops · error · Error

clone of ${url}@${sha.slice(0, 10)} failed — ${err.stderr ?

Error message

clone of ${url}@${sha.slice(0, 10)} failed — ${err.stderr ? String(err.stderr).slice(0, 200) : err.message}

What it means

Thrown by safeClone() when the pinned-shallow clone (init → remote add → fetch --depth 1 → checkout FETCH_HEAD) fails for any reason. The error message includes the truncated stderr so the underlying git failure (network, unknown revision, auth) is visible, and the temp dir is cleaned up before throwing.

Source

Thrown at plugin-install.mjs:52

  if (!m) throw new Error(`repo must be named "career-ops-plugin-<name>" (got "${repoName}")`);
  return { url, id: m[1] };
}

/** Clone the EXACT pinned SHA into a fresh temp dir. Returns the temp dir path. */
export function safeClone(url, sha) {
  if (!SHA_RE.test(sha || '')) throw new Error(`a 40-hex commit --sha is required (got ${JSON.stringify(sha)})`);
  const dir = mkdtempSync(path.join(tmpdir(), 'co-plugin-'));
  const git = (...args) => execFileSync('git', ['-c', 'protocol.ext.allow=never', '-c', 'protocol.file.allow=never', ...args], { stdio: ['ignore', 'ignore', 'pipe'], timeout: 120_000 });
  try {
    git('-C', dir, 'init', '-q');
    git('-C', dir, 'remote', 'add', 'origin', '--', url);
    git('-C', dir, 'fetch', '--depth', '1', '--no-tags', '-q', 'origin', sha);
    git('-C', dir, 'checkout', '-q', 'FETCH_HEAD');
    rmSync(path.join(dir, '.git'), { recursive: true, force: true }); // drop VCS metadata (and any hooks)
    return dir;
  } catch (err) {
    rmSync(dir, { recursive: true, force: true });
    throw new Error(`clone of ${url}@${sha.slice(0, 10)} failed — ${err.stderr ? String(err.stderr).slice(0, 200) : err.message}`);
  }
}

/** Check the minimum file set + a valid manifest whose id matches `expectId`. */
export function validateInstall(dir, expectId) {
  const problems = [];
  for (const f of MIN_FILES) if (!existsSync(path.join(dir, f))) problems.push(`missing required file: ${f}`);
  if (problems.length) return { ok: false, problems, manifest: null };
  let parsed;
  try { parsed = JSON.parse(readFileSync(path.join(dir, 'manifest.json'), 'utf8')); }
  catch (e) { return { ok: false, problems: [`manifest.json invalid JSON: ${e.message}`], manifest: null }; }
  // validateManifest wants the dir to BE the plugin dir + the basename to equal id.
  const tmpNamed = path.join(path.dirname(dir), expectId);
  if (dir !== tmpNamed) { try { renameSync(dir, tmpNamed); dir = tmpNamed; } catch { /* validate in place using expectId */ } }
  const manifest = validateManifest(parsed, dir, expectId);
  if (!manifest) return { ok: false, problems: ['manifest failed validation (see ⚠️ above)'], manifest: null, dir };
  const audit = auditPlugin(dir);
  if (!audit.ok) return { ok: false, problems: audit.findings.map(f => `${f.file}: ${f.issue}`), manifest, dir };

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Verify the SHA exists: git ls-remote https://github.com/<owner>/<repo> or check GitHub's commits list.
  2. Confirm git is installed and reachable: git --version.
  3. Check network reachability to github.com (the message's stderr will indicate the cause).
  4. Re-copy the SHA and retry with a confirmed-valid full commit hash.

Example fix

// before: SHA not present in repo
safeClone(url, '0000000000000000000000000000000000000000');
// after: confirmed-present SHA
safeClone(url, gitResolvedSha);
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
  const dir = safeClone(url, sha);
} catch (e) {
  if (/clone of .* failed/.test(e.message)) {
    // inspect e.message stderr: unknown revision vs network vs git-missing
    // verify sha via git ls-remote, then retry once
  } else throw e;
}

Prevention

When it happens

Trigger: The pinned SHA does not exist in the repo (unknown revision); network error reaching github.com; git not installed or not on PATH; git protocol.file/protocol.ext blocked config interferes; fetch timeout (120s).

Common situations: Typo in the 40-hex SHA (lookalike characters); the commit was force-pushed away or the branch history rewritten; air-gapped environment with no GitHub reachability; CI runner lacking git.

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/087a82e8a899cdba. Report an issue: GitHub.