pnpm/pnpm · error · PnpmError

NO_BUGS_URL

NO_BUGS_URL

Error message

The current project does not have a bug tracker URL. Add a "bugs" or "repository" field to its manifest.

What it means

Thrown by `pnpm bugs` when run in the current project and the project manifest yields no usable bug tracker URL. pickBugsUrl only accepts an http(s) URL from the `bugs` field (string or {url}) or, failing that, the `repository` field — a missing or non-http value (e.g. a bugs field that is only an email) leaves nothing to open.

Source

Thrown at pnpm11/deps/inspection/commands/src/bugs/index.ts:55

    ? [await getBugsUrlFromCurrentProject(opts)]
    : await Promise.all(params.map((spec) => getBugsUrlFromRegistry(opts, spec)))
  for (const url of urls) {
    // eslint-disable-next-line no-await-in-loop
    await open(url)
  }
}

async function getBugsUrlFromCurrentProject (
  opts: Pick<Config, 'dir' | 'engineStrict' | 'nodeVersion' | 'supportedArchitectures'>
): Promise<string> {
  const manifest = await readProjectManifestOnly(opts.dir, {
    engineStrict: opts.engineStrict,
    nodeVersion: opts.nodeVersion,
    supportedArchitectures: opts.supportedArchitectures,
  })
  const url = pickBugsUrl({ bugs: manifest.bugs, repository: manifest.repository })
  if (!url) {
    throw new PnpmError(
      'NO_BUGS_URL',
      'The current project does not have a bug tracker URL. Add a "bugs" or "repository" field to its manifest.'
    )
  }
  return url
}

async function getBugsUrlFromRegistry (
  opts: Config & ConfigContext,
  packageSpec: string
): Promise<string> {
  const info = await fetchPackageInfo(opts, packageSpec)
  const url = pickBugsUrl({ bugs: info.bugs, repository: info.repository })
  if (!url) {
    throw new PnpmError('NO_BUGS_URL', `The package "${info.name}" does not have a bug tracker URL.`)
  }
  return url
}

View on GitHub (pinned to 5b11d3a15b)

Solutions

  1. Add a "bugs" field with an http(s) URL to package.json (e.g. "bugs": { "url": "https://github.com/user/repo/issues" })
  2. Or add a "repository" field whose URL can be resolved to the tracker
  3. If you only have an email, note that `pnpm bugs` will not open it — a URL is required

Example fix

// before
{
  "name": "my-pkg"
}

// after
{
  "name": "my-pkg",
  "bugs": { "url": "https://github.com/user/my-pkg/issues" }
}
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs'

const manifest = JSON.parse(fs.readFileSync('package.json', 'utf8'))
const hasBugsUrl = typeof manifest.bugs === 'string' || typeof manifest.bugs?.url === 'string' || manifest.repository != null
if (!hasBugsUrl) {
  throw new Error('add a "bugs" or "repository" field before running pnpm bugs')
}

Type guard

function hasHttpBugsUrl (m: { bugs?: string | { url?: string } }): boolean {
  const url = typeof m.bugs === 'string' ? m.bugs : m.bugs?.url
  return url != null && /^https?:\/\//.test(url)
}

Try / catch

try {
  await bugsCmd(opts)
} catch (err) {
  if (err instanceof PnpmError && err.code === 'NO_BUGS_URL') {
    // open the package page instead, or print the missing-manifest-field hint
  } else throw err
}

Prevention

When it happens

Trigger: Running `pnpm bugs` in a package.json with no `bugs` and no `repository` field; having `bugs: { email: ... }` with no url and no repository; repository set to a non-URL shorthand that pickBugsUrl cannot turn into an http(s) link.

Common situations: New scaffolds generated from minimal templates; private packages never given repository metadata; manifests where repository is an object with only a `directory` key.

Related errors


AI-assisted analysis of pnpm/pnpm@5b11d3a15b (2026-08-16). Data as JSON: /api/errors/af70f1dc1b4f23de. Report an issue: GitHub.