nodejs/node · error · Error
Token ID "${id}" was ambiguous, a new token may have been cr
Error message
Token ID "${id}" was ambiguous, a new token may have been created since you last ran `npm token list`. What it means
Thrown by `npm token rm` when the given id is a prefix that matches more than one token's `key`. npm refuses to guess which token to delete, and hints that a newer token may have shifted the matching set since the last `npm token list`.
Source
Thrown at deps/npm/lib/commands/token.js:126
}
}
async rm (args) {
if (args.length === 0) {
throw this.usageError('`<tokenKey>` argument is required.')
}
const json = this.npm.config.get('json')
const parseable = this.npm.config.get('parseable')
const toRemove = []
log.info('token', `removing ${toRemove.length} tokens`)
const tokens = await paginate('/-/npm/v1/tokens', this.npm.flatOptions)
for (const id of args) {
const matches = tokens.filter(token => token.key.indexOf(id) === 0)
if (matches.length === 1) {
toRemove.push(matches[0].key)
} else if (matches.length > 1) {
throw new Error(
`Token ID "${id}" was ambiguous, a new token may have been created since you last ran \`npm token list\`.`
)
} else {
const tokenMatches = tokens.some(t => id.indexOf(t.token) === 0)
if (!tokenMatches) {
throw new Error(`Unknown token id or value "${id}".`)
}
toRemove.push(id)
}
}
for (const tokenKey of toRemove) {
await otplease(this.npm, this.npm.flatOptions, opts =>
fetch(`/-/npm/v1/tokens/token/${tokenKey}`, {
...opts,
method: 'DELETE',
ignoreBody: true,
})View on GitHub (pinned to 1b2de5e052)
Solutions
- Run `npm token list` to get current full token ids, then pass a longer/unique prefix or the full id.
- Pass the complete token key to disambiguate.
- If prefix collisions are common, revoke tokens individually with the full id.
Example fix
// before npm token rm abc123 // matches 2 tokens // after npm token rm abc123def456-full-key
Defensive patterns
Strategy: validation
Validate before calling
function resolveTokenId(id, tokens) {
const matches = tokens.filter(t => t.key.indexOf(id) === 0)
if (matches.length > 1) {
throw new Error(`Token id "${id}" is ambiguous (${matches.length} matches). Use the full key.`)
}
return matches[0]?.key ?? null
} Prevention
- Always pass the full token id/key, not a prefix.
- Re-run `npm token list` immediately before revoking to get a current view.
- In rotation scripts, target one token at a time with its full key.
When it happens
Trigger: In the revoke loop, `tokens.filter(t => t.key.indexOf(id) === 0).length > 1` — the id is a prefix of two or more token keys.
Common situations: Using a short id prefix that several tokens share; revoking after new tokens were created (CI rotations) that share the same prefix; copying only the first few characters of a token id.
Related errors
- Unknown token id or value "${id}".
- ${argv[2]} not recognized
- The ${key} option is protected, and cannot be retrieved in t
- You must specify a tag using --tag when publishing a prerele
- You cannot publish over the previously published versions: $
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/6564ff2f3005dc9a.
Report an issue: GitHub.