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
- Add a "bugs" field with an http(s) URL to package.json (e.g. "bugs": { "url": "https://github.com/user/repo/issues" })
- Or add a "repository" field whose URL can be resolved to the tracker
- 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
- Include a "bugs" URL in every package.json your tooling scaffolds
- Use full http(s) URLs, not email-only bugs fields or git shorthands
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.