yarnpkg/yarn · error · MessageError

Unknown fetcher for $0

Error message

Unknown fetcher for $0

What it means

Thrown by `fetchOneRemote` when `fetchers[remote.type]` is undefined — i.e. the package's remote `type` field does not correspond to any registered fetcher (the known types are the keys of `src/fetchers/index.js`, e.g. `archive`, `git`, `tarball`, `link`, `copy`, plus directory). Yarn cannot fetch a package whose remote type it does not recognize.

Source

Thrown at src/package-fetcher.js:64

  };
}

export async function fetchOneRemote(
  remote: PackageRemote,
  name: string,
  version: string,
  dest: string,
  config: Config,
): Promise<FetchedMetadata> {
  // Mock metadata for symlinked dependencies
  if (remote.type === 'link') {
    const mockPkg: Manifest = {_uid: '', name: '', version: '0.0.0'};
    return Promise.resolve({resolved: null, hash: '', dest, package: mockPkg, cached: false});
  }

  const Fetcher = fetchers[remote.type];
  if (!Fetcher) {
    throw new MessageError(config.reporter.lang('unknownFetcherFor', remote.type));
  }

  const fetcher = new Fetcher(dest, remote, config);
  if (await config.isValidModuleDest(dest)) {
    return fetchCache(dest, fetcher, config, remote);
  }

  // remove as the module may be invalid
  await fs.unlink(dest);

  try {
    return await fetcher.fetch({
      name,
      version,
    });
  } catch (err) {
    try {
      await fs.unlink(dest);

View on GitHub (pinned to c2dda503f3)

Solutions

  1. Regenerate the lockfile: `rm yarn.lock && yarn install` so remote types are written by your current Yarn.
  2. Ensure you are not mixing Yarn classic with Berry/patched binaries on the same lockfile.
  3. If using a custom resolver, verify it emits a type present in `src/fetchers/index.js`.
  4. Inspect the lockfile entry for the offending package and remove the bad remote block.

Example fix

# before (yarn.lock has unknown remote type)
"foo@1.0.0":
  resolved "weird-protocol://..."
# fix: regenerate
rm yarn.lock
yarn install
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_FETCHER_TYPES = new Set(['archive', 'git', 'tarball', 'link', 'copy', 'directory']);
function validateRemoteType(remote) {
  if (remote.type !== 'link' && !KNOWN_FETCHER_TYPES.has(remote.type)) {
    throw new Error(`Unknown fetcher type '${remote.type}' — regenerate yarn.lock.`);
  }
}

Type guard

function isKnownFetcherType(type, fetchers) {
  return type === 'link' || Object.prototype.hasOwnProperty.call(fetchers, type);
}

Try / catch

try {
  return await fetchOneRemote(remote, name, version, dest, config);
} catch (err) {
  if (err instanceof MessageError && err.message.startsWith('Unknown fetcher for')) {
    reporter.error('Lockfile references an unsupported remote type. Regenerate: rm yarn.lock && yarn install');
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: A package reference carries a `remote.type` value not present in the fetchers map. This typically arises from a hand-edited or corrupted yarn.lock, a lockfile from an incompatible Yarn fork/version, or a custom resolver that emitted an unsupported remote type.

Common situations: Corrupted yarn.lock with a bad remote type. Mixing Yarn with a custom resolver plugin that registered a type Yarn classic does not ship. A lockfile produced by a patched Yarn being opened by stock Yarn.

Related errors


AI-assisted analysis of yarnpkg/yarn@c2dda503f3 (2026-08-13). Data as JSON: /api/errors/33b84744ed67a15a. Report an issue: GitHub.