{"record":{"id":"8050bae199d37584","repo":"pnpm/pnpm","slug":"spec-not-supported-by-any-resolver","errorCode":"SPEC_NOT_SUPPORTED_BY_ANY_RESOLVER","errorMessage":"${specifier} isn't supported by any available resolver.","messagePattern":"(.+?) isn't supported by any available resolver\\.","errorType":"exception","errorClass":"PnpmError","httpStatus":null,"severity":"error","filePath":"pnpm11/resolving/default-resolver/src/index.ts","lineNumber":158,"sourceCode":"          await _resolveFromLocalScheme(wantedDependency as { bareSpecifier: string }, opts)\n        )) ??\n        await _resolveNodeRuntime(wantedDependency, opts) ??\n        await _resolveDenoRuntime(wantedDependency, opts) ??\n        await _resolveBunRuntime(wantedDependency, opts) ??\n        // Named-registry runs between the explicit local schemes above and the\n        // path-shape match below, so `<alias>:@scope/pkg` reaches the configured\n        // registry while a colliding `file:`/`link:`/`workspace:` alias cannot\n        // hijack the built-in protocols.\n        await resolveFromNamedRegistry(wantedDependency, opts as ResolveFromNpmOptions) ??\n        (wantedDependency.bareSpecifier\n          ? await _resolveFromLocalPath(wantedDependency as { bareSpecifier: string }, opts)\n          : null)\n      if (!resolution) {\n        let specifier = `${wantedDependency.alias ? wantedDependency.alias + '@' : ''}${wantedDependency.bareSpecifier ?? ''}`\n        if (specifier !== '') {\n          specifier = `\"${specifier}\"`\n        }\n        throw new PnpmError(\n          'SPEC_NOT_SUPPORTED_BY_ANY_RESOLVER',\n          `${specifier} isn't supported by any available resolver.`)\n      }\n      return resolution\n    },\n    resolveLatest: async (query, opts) => {\n      const info = (await resolveLatestFromNpm(query, opts)) ??\n        (await resolveLatestFromJsr(query, opts)) ??\n        (await resolveLatestFromGit(query)) ??\n        (await resolveLatestFromTarball(query)) ??\n        (await resolveLatestFromLocal(query)) ??\n        (await _resolveLatestNodeRuntime(query, opts)) ??\n        (await _resolveLatestDenoRuntime(query, opts)) ??\n        (await _resolveLatestBunRuntime(query, opts)) ??\n        (await resolveLatestFromNamedRegistry(query, opts))\n      return info\n    },\n    clearCache,","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/pnpm/pnpm/blob/6261b7f388016d57ca6b90340342411cd1d0d00f/pnpm11/resolving/default-resolver/src/index.ts#L140-L176","documentation":"The default resolver dispatches a wanted dependency through a fixed chain — custom resolvers, npm, jsr:, git, tarball URLs, the local schemes (file:/link:/workspace:), node:/deno:/bun: runtime specifiers, named registries, and finally bare local paths. If every resolver declines, resolve throws SPEC_NOT_SUPPORTED_BY_ANY_RESOLVER naming the alias and bare specifier.","triggerScenarios":"A dependency spec no resolver claims: a typo'd protocol ('worskpace:*', 'htp://…'), a protocol pnpm does not support, an alias whose bare part matches nothing, or a bare path that does not exist on disk so the final path resolver declines.","commonSituations":"Copy-paste typos in package.json specs; protocols from other ecosystems; a proprietary protocol that requires a customResolver plugin that is not registered; deleted local directories referenced by path.","solutions":["Fix the specifier spelling — most commonly workspace:*, file:./…, or a valid registry name/URL","Use a supported form: npm name/range/tag, jsr:@scope/name, git URL (optionally #semver:^1), tarball URL, file:, link:, workspace:, node:/deno:/bun:, or an alias to a named registry","For proprietary protocols, register a customResolver plugin so the chain has a handler"],"exampleFix":"// package.json — before\n\"@scope/tools\": \"worskpace:*\"\n\n// after\n\"@scope/tools\": \"workspace:*\"","handlingStrategy":"type-guard","validationCode":"import fs from 'node:fs'\n\n// Reject specs no built-in resolver can claim before running install.\nexport function checkSpecifierSupported (alias: string | undefined, spec: string): void {\n  const protocols = ['workspace:', 'file:', 'link:', 'jsr:', 'http://', 'https://', 'node:', 'deno:', 'bun:']\n  const bare = spec\n  const looksLikeProtocol = /^[a-zA-Z][\\w+.-]*:/.test(bare)\n  if (looksLikeProtocol && !protocols.some((p) => bare.startsWith(p))) {\n    throw new Error(`Unsupported protocol in ${alias ?? ''}${alias ? '@' : ''}${spec}`)\n  }\n  if (!looksLikeProtocol && bare.startsWith('.') && !fs.existsSync(bare)) {\n    throw new Error(`Local path dependency does not exist: ${bare}`)\n  }\n}","typeGuard":"const SUPPORTED_PREFIXES = ['workspace:', 'file:', 'link:', 'jsr:', 'node:', 'deno:', 'bun:']\nconst GIT_HOSTS = /^(git|git\\+ssh|git\\+https|ssh|https?):\\/\\//\nconst TARBALL_URL = /^https?:\\/\\/.+\\.(tgz|tar\\.gz)(#.*)?$/\n\nexport function isResolvableSpecifier (spec: string): boolean {\n  if (SUPPORTED_PREFIXES.some((p) => spec.startsWith(p))) return true\n  if (GIT_HOSTS.test(spec) || TARBALL_URL.test(spec)) return true\n  if (/^\\.\\.(\\/|$)/.test(spec)) return true // bare local path\n  return /^[^:/]/.test(spec) // plain npm name/range/tag\n}","tryCatchPattern":"try {\n  await resolveDependencies(deps, opts)\n} catch (err) {\n  if (err instanceof PnpmError && err.code === 'SPEC_NOT_SUPPORTED_BY_ANY_RESOLVER') {\n    // The message quotes the offending alias/spec; fix the manifest or register a custom resolver\n    throw new Error(`Unresolvable dependency spec: ${err.message}`)\n  }\n  throw err\n}","preventionTips":["Lint package.json specs in CI with isResolvableSpecifier to catch protocol typos like 'worskpace:'","Add internal deps with pnpm add --workspace so the protocol is always spelled correctly","For proprietary protocols, register a customResolver plugin before adopting the spec in manifests"],"tags":["resolving","dependency-specifier","protocol","install"],"backgroundTag":"unsupported-dependency-protocol","analyzedSha":"6261b7f388016d57ca6b90340342411cd1d0d00f","analyzedAt":"2026-08-17T18:30:54.750Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}