vercel-labs/agent-skills · error · Error

VERCEL_VERSION_UNPARSEABLE

VERCEL_VERSION_UNPARSEABLE

Error message

VERCEL_VERSION_UNPARSEABLE: ${raw}

What it means

Thrown by checkCliVersion() when `vercel --version` succeeded (no rejection) but its stdout did not contain a `major.minor.patch` triple matching /(\d+)\.(\d+)\.(\d+)/. The version gate cannot compare against MIN_CLI_VERSION=[53,0,0] without parseable semver, so the skill refuses to proceed rather than guessing. Typical causes are a nonstandard CLI build, a wrapper that prefixes banners, or stderr content captured where stdout was expected.

Source

Thrown at skills/vercel-optimize/lib/vercel.mjs:102

    err.code = 'ENOENT';
    throw err;
  }
  return await exec(command.file, [...command.prefix, ...args], { windowsHide: true, ...opts });
}

const MIN_CLI_VERSION = [53, 0, 0];

// Pre-v53 lacks `vercel metrics` and `vercel contract`.
export async function checkCliVersion() {
  let raw;
  try {
    const { stdout } = await runVercel(['--version']);
    raw = stdout.trim();
  } catch (err) {
    throw new Error('VERCEL_NOT_INSTALLED: `vercel` CLI not found in PATH. Install with `npm i -g vercel@latest`.');
  }
  const m = raw.match(/(\d+)\.(\d+)\.(\d+)/);
  if (!m) throw new Error(`VERCEL_VERSION_UNPARSEABLE: ${raw}`);
  const v = [Number(m[1]), Number(m[2]), Number(m[3])];
  for (let i = 0; i < 3; i++) {
    if (v[i] > MIN_CLI_VERSION[i]) return v;
    if (v[i] < MIN_CLI_VERSION[i]) {
      throw new Error(
        `VERCEL_CLI_TOO_OLD: have ${v.join('.')}, need >= ${MIN_CLI_VERSION.join('.')}. Upgrade with \`npm i -g vercel@latest\`.`
      );
    }
  }
  return v;
}

export async function checkAuth() {
  try {
    await runVercel(['whoami']);
  } catch {
    throw new Error('NOT_AUTH: run `vercel login`.');
  }

View on GitHub (pinned to b8caa260a4)

Solutions

  1. Run `vercel --version` manually and confirm the output contains a `X.Y.Z` triple on stdout.
  2. Remove any shell alias, function, or wrapper that prepends non-version text to the version command's stdout.
  3. Reinstall the official CLI: `npm i -g vercel@latest`.
  4. If you maintain a wrapper, ensure it forwards stdout verbatim and writes banners to stderr.

Example fix

// before
const m = raw.match(/(\d+)\.(\d+)\.(\d+)/);
if (!m) throw new Error(`VERCEL_VERSION_UNPARSEABLE: ${raw}`);

// after — tolerate build metadata / prerelease suffixes
const m = raw.match(/(\d+)\.(\d+)\.(\d+)(?:-[\w.]+)?/);
if (!m) throw new Error(`VERCEL_VERSION_UNPARSEABLE: ${JSON.stringify(raw)}`);
Defensive patterns

Strategy: validation

Validate before calling

import { execFileSync } from 'node:child_process';
function assertVersionParses() {
  const out = execFileSync('vercel', ['--version'], { encoding: 'utf-8' });
  if (!/\d+\.\d+\.\d+/.test(out)) {
    throw new Error(`vercel --version output is unparseable: ${JSON.stringify(out)}`);
  }
}
assertVersionParses();

Try / catch

try {
  await checkCliVersion();
} catch (err) {
  if (err.message.startsWith('VERCEL_VERSION_UNPARSEABLE')) {
    // inspect raw output, strip wrappers/aliases, then retry once
    console.error('Could not parse CLI version. Remove any alias/wrapper around `vercel`.');
  }
  throw err;
}

Prevention

When it happens

Trigger: A forked or aliased `vercel` binary that prints a non-semver banner (e.g. a dev build tagged `vercel-dev-local`); a shell alias that echoes extra lines to stdout before the real version; a future CLI that changes `--version` output format; stdout captured as empty because the real version went to stderr.

Common situations: Custom internal CLI wrapper around `vercel`; locale/environment that alters numeric formatting; a proxy/shim that injects a sponsor line into stdout; running an unpublished/canary build whose version string is a git SHA.

Related errors


AI-assisted analysis of vercel-labs/agent-skills@b8caa260a4 (2026-08-13). Data as JSON: /api/errors/87c63f859dbda7db. Report an issue: GitHub.