no-floating-wake-locks
Require WakeLockSentinel handles to be retained so they can be released.
Rule catalog ID: R016
Targeted pattern scopeโ
This rule targets screen wake lock requests:
navigator.wakeLock.request(...)window.navigator.wakeLock.request(...)globalThis.navigator.wakeLock.request(...)
The rule reports wake lock requests whose resulting WakeLockSentinel is
immediately discarded, including await expressions that do not store, return,
or pass the sentinel to another owner.
What this rule reportsโ
The rule reports:
- standalone wake lock requests such as
navigator.wakeLock.request("screen"); - voided wake lock requests such as
void navigator.wakeLock.request("screen"); - awaited standalone requests such as
await navigator.wakeLock.request("screen");
It intentionally allows promise chains and lifecycle-manager calls that receive the sentinel. The rule focuses on directly unowned wake lock handles.
Why this rule existsโ
navigator.wakeLock.request() resolves to a WakeLockSentinel. The sentinel is
the handle that can be released manually with release(), and applications
usually need to retain it to update UI, react to release events, or release the
wake lock during cleanup.
Incorrectโ
navigator.wakeLock.request("screen");
void navigator.wakeLock.request("screen");
async function keepAwake() {
await navigator.wakeLock.request("screen");
}
Correctโ
async function keepAwake() {
const sentinel = await navigator.wakeLock.request("screen");
await sentinel.release();
}
async function keepAwake() {
return navigator.wakeLock.request("screen");
}
async function keepAwake() {
registerWakeLock(await navigator.wakeLock.request("screen"));
}
Behavior and migration notesโ
Store the sentinel in the owner that will call release(). For UI code, that is
usually a component, route, or media/session controller. Applications should
also consider listening for the sentinel's release event because user agents
can release wake locks automatically.
This rule does not autofix. Choosing the owning lifecycle and release behavior is a semantic decision.
ESLint flat config exampleโ
import runtimeCleanup from "eslint-plugin-runtime-cleanup";
export default [
runtimeCleanup.configs.recommended,
];
When not to use itโ
Do not enable this rule for code where wake lock ownership is intentionally
hidden inside an abstraction that the rule cannot see. Prefer wrapping
navigator.wakeLock.request() in that abstraction and disabling the rule only
inside the wrapper if needed.