denoland/deno · error · DOMException
NotSupportedError
NotSupportedError
Error message
'name' must not start with '-'
What it means
The Web Locks API reserves lock names beginning with a hyphen ('-') for internal use, so LockManager.request rejects them with a DOMException named NotSupportedError, thrown from ext/web/locks.js after option conversion but before acquiring anything. The check uses startsWith on the raw name string. Nothing was locked when this throws.
Source
Thrown at ext/web/locks.js:124
if (arguments.length === 2) {
options = {};
callback = optionsOrCallback;
} else {
options = optionsOrCallback;
}
if (typeof callback !== "function") {
throw new TypeError("callback must be a function");
}
options = webidl.converters.LockOptions(
options,
prefix,
"Argument 2",
);
if (StringPrototypeStartsWith(name, "-")) {
throw new DOMException(
"'name' must not start with '-'",
"NotSupportedError",
);
}
if (options.steal && options.ifAvailable) {
throw new DOMException(
"'steal' and 'ifAvailable' are exclusive",
"NotSupportedError",
);
}
if (options.steal && options.mode !== "exclusive") {
throw new DOMException(
"'mode' must be 'exclusive' if 'steal' is specified",
"NotSupportedError",
);
}
if (options.signal && (options.steal || options.ifAvailable)) {
throw new DOMException(View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Rename the lock so it does not start with '-', e.g. 'mylock' or 'app:mylock'.
- If names derive from user input, sanitize: name.replace(/^-+/, "").
- Validate generated names with a check like name.startsWith('-') before calling request.
- Pick a namespace separator that cannot appear at position 0, such as ':' or '__'.
Example fix
// before
navigator.locks.request("-job:" + id, cb);
// after
navigator.locks.request("job:" + id, cb); Defensive patterns
Strategy: validation
Validate before calling
function lockName(name) {
const n = name.replace(/^-+/, "");
if (n.startsWith("-")) throw new Error(`invalid lock name: ${name}`);
return n;
}
navigator.locks.request(lockName(raw), cb); Type guard
function isValidLockName(name) {
return typeof name === "string" && name.length > 0 && !name.startsWith("-");
} Try / catch
try { await navigator.locks.request(name, cb); } catch (e) { if (e.name === "NotSupportedError" && e.message.includes("'-'")) await navigator.locks.request(name.replace(/^-+/, ""), cb); else throw e; } Prevention
- Pick a lock-name scheme that cannot start with '-' (e.g. 'app:resource').
- Sanitize user-derived names at the system boundary.
- Add a unit test for the naming helper covering leading hyphens.
When it happens
Trigger: navigator.locks.request("-mylock", cb); names built from user input or generated IDs that start with '-'; prefixing names with '-' as a namespace convention ('-app:resource').
Common situations: Auto-generated lock keys from slugs or CLI-style flags ('--job-42'); copying a naming scheme from a queue/redis library where '-' prefixes are allowed; concatenating '-' separators after an empty first segment, producing a leading '-'.
Related errors
- callback must be a function
- AbortError
- SyntaxError
- BenchContext::start() has already been invoked
- ${prefix}Linter plugin name must only contain lowercase lett
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/281bee825e043937.
Report an issue: GitHub.