nodejs/node · info · Error
canceled
Error message
canceled
What it means
Thrown by npm's openUrlPrompt when a SIGINT (Ctrl+C) is received on the readline interface while waiting for the user to press ENTER to open a URL in the browser. It represents an intentional user cancellation of a browser-based auth/OTP flow (e.g. npm login / adduser / publish with web auth), not a malfunction. The error is created as a plain Error (not AbortError), so the surrounding catch (which only suppresses AbortError) re-throws it.
Source
Thrown at deps/npm/lib/utils/open-url.js:76
assertValidUrl(url)
outputMsg(json, title, url)
if (browser === false || !process.stdin.isTTY || !process.stdout.isTTY) {
return
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
try {
await input.read(() => Promise.race([
rl.question(prompt, { signal }),
once(rl, 'error'),
once(rl, 'SIGINT').then(() => {
throw new Error('canceled')
}),
]))
rl.close()
await openUrl(npm, url, 'Browser unavailable. Please open the URL manually')
} catch (err) {
rl.close()
if (err.name !== 'AbortError') {
throw err
}
}
}
// Rearrange arguments and return a function that takes the two arguments returned from the npm-profile methods that take an opener
const createOpener = (npm, title, prompt = 'Press ENTER to open in the browser...') =>
(url, opts) => openUrlPrompt(npm, url, title, prompt, opts)
module.exports = {
openUrl,View on GitHub (pinned to 1b2de5e052)
Solutions
- Treat it as expected: this is the user cancelling, so simply re-run the command when ready or use a non-interactive auth method (e.g. npm config set //registry/:_authToken).
- If running in CI, ensure stdin is not a TTY (process.stdin.isTTY === false) so the prompt is skipped entirely, or pre-set credentials via NPM_TOKEN.
- If forwarding SIGINT unintentionally, run the npm command in a process group that does not relay Ctrl+C to the child.
- To suppress in tooling, wrap the npm invocation and treat exit code / stderr containing 'canceled' as a benign cancellation.
Example fix
// before: interactive prompt blocks CI, Ctrl+C surfaces as fatal 'canceled' // after: skip the prompt by providing a token non-interactively npm config set //registry.npmjs.org/:_authToken "$NPM_TOKEN" npm publish --access public
Defensive patterns
Strategy: try-catch
Try / catch
// openUrlPrompt is internal to npm; guard at the process level when invoking npm.
const { spawnSync } = require('node:child_process')
const res = spawnSync('npm', ['login'], { stdio: 'inherit' })
if (res.status !== 0 && /canceled/.test(String(res.stderr))) {
console.log('user cancelled the browser login flow')
} Prevention
- Provide credentials non-interactively (NPM_TOKEN / _authToken) so the browser prompt is never reached.
- Ensure CI runners have a non-TTY stdin so openUrlPrompt returns early without prompting.
- Do not forward SIGINT to the npm child process if cancellation is not intended.
When it happens
Trigger: Running a command that calls createOpener/openUrlPrompt (npm login, npm adduser, npm publish with provenance/OTP web flow, npm token create), seeing the 'Press ENTER to open in the browser...' prompt, and pressing Ctrl+C (or a parent process forwarding SIGINT) before pressing ENTER.
Common situations: User changes their mind mid-login; a wrapper/CI process forwards Ctrl+C; an interactive prompt is mistakenly reached in a pseudo-TTY where Ctrl+C is sent automatically; the browser failed to open and the user aborts.
Related errors
- The ${key} option is protected, and cannot be retrieved in t
- ${argv[2]} not recognized
- First argument `orgname` is required.
- Second argument `username` is required.
- Third argument `role` must be one of `owner`, `admin`, or `d
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/159dd1fe83760e1c.
Report an issue: GitHub.