Environment information
CLI:
Version: 2.5.6
Color support: false
Platform:
CPU Architecture: x86_64
OS: windows
Environment:
BIOME_DISTRIBUTION: npm
BIOME_LOG_PATH: unset
BIOME_LOG_PREFIX_NAME: unset
BIOME_LOG_LEVEL: unset
BIOME_LOG_KIND: unset
BIOME_CONFIG_PATH: unset
BIOME_THREADS: unset
BIOME_WATCHER_KIND: unset
BIOME_WATCHER_POLLING_INTERVAL: unset
NO_COLOR: 1
TERM: unset
JS_RUNTIME_VERSION: v24.16.0
JS_RUNTIME_NAME: node
NODE_PACKAGE_MANAGER: bun/1.3.14
Biome Configuration:
Status: Loaded successfully.
Path: biome.json
Formatter enabled: true
Linter enabled: true
Assist enabled: true
VCS enabled: false
HTML full support enabled: unset
Linter:
JavaScript enabled: unset
JSON enabled: unset
CSS enabled: unset
GraphQL enabled: unset
Recommended: unset
Enabled rules:
suspicious/noUnnecessaryConditions
Workspace:
Open Documents: 0
Rule name
suspicious/noUnnecessaryConditions
Playground link
https://biomejs.dev/playground/?lintRules=all&tab=diagnostics&code=YwBvAG4AcwB0ACAAZwB1AGEAcgBkACAAPQAgAHsAIABjAHUAcgByAGUAbgB0ADoAIABmAGEAbABzAGUAIAB9ADsACgAKAGUAeABwAG8AcgB0ACAAZgB1AG4AYwB0AGkAbwBuACAAcgB1AG4ATwBuAGMAZQAoACkAIAB7AAoACQBpAGYAIAAoAGcAdQBhAHIAZAAuAGMAdQByAHIAZQBuAHQAKQAgAHsACgAJAAkAcgBlAHQAdQByAG4AOwAKAAkAfQAKAAkAZwB1AGEAcgBkAC4AYwB1AHIAcgBlAG4AdAAgAD0AIAB0AHIAdQBlADsACgB9AAoACgAvAC8AIABDAG8AbgB0AHIAbwBsADoAIAB0AGgAZQAgAHMAYQBtAGUAIABsAG8AZwBpAGMAIABvAG4AIABhACAAYgBpAG4AZABpAG4AZwAgAHIAYQB0AGgAZQByACAAdABoAGEAbgAgAGEAIABwAHIAbwBwAGUAcgB0AHkAIABpAHMAIABuAG8AdAAgAGYAbABhAGcAZwBlAGQALgAKAGwAZQB0ACAAZgBsAGEAZwAgAD0AIABmAGEAbABzAGUAOwAKAAoAZQB4AHAAbwByAHQAIABmAHUAbgBjAHQAaQBvAG4AIAByAHUAbgBPAG4AYwBlAEIAaQBuAGQAaQBuAGcAKAApACAAewAKAAkAaQBmACAAKABmAGwAYQBnACkAIAB7AAoACQAJAHIAZQB0AHUAcgBuADsACgAJAH0ACgAJAGYAbABhAGcAIAA9ACAAdAByAHUAZQA7AAoAfQAKAA%3D%3D
Expected result
No diagnostic should be emitted on line 4. guard.current is assigned true on line 7, so the condition is reachable.
Reproduction
const guard = { current: false };
export function runOnce() {
if (guard.current) { // <-- "This condition is always falsy."
return;
}
guard.current = true;
}
// Control: the same logic on a binding rather than a property is not flagged.
let flag = false;
export function runOnceBinding() {
if (flag) {
return;
}
flag = true;
}
biome lint on 2.5.6, with suspicious/noUnnecessaryConditions as the only enabled rule:
repro.ts:4:6 lint/suspicious/noUnnecessaryConditions ━━━━━━━━━━━━━━━━━━━━━━━━━━
× This condition is always falsy.
3 │ export function runOnce() {
> 4 │ if (guard.current) {
│ ^^^^^^^^^^^^^
5 │ return;
6 │ }
i The value's type can never be truthy, so this check is redundant.
Found 1 error.
Analysis
The property keeps the literal type false from its initialiser, and the later assignment is not taken into account. The control case in the same file shows the asymmetry: the mutation exemption added in #10108 covers plain bindings, but not member expressions. TypeScript widens the property to boolean here and reports nothing.
Other shapes that reproduce
const r = useRef(false); … r.current = true — this is the common React in-flight guard against double submission, and it is where I hit the false positive in real code.
const r = useRef<boolean>(false) — an explicit type argument does not help; the initialiser still wins.
const r = useRef(0); … r.current = 1 — same behaviour, reported as always falsy.
const r = useRef(true); … r.current = false — reported as always truthy.
An as cast on the initialiser (useRef(false as boolean)) silences it, which is consistent with the literal type being the cause.
Impact
The reported code is not redundant, so acting on the diagnostic removes a working guard. There is no safe automatic fix; the only option today is a biome-ignore comment on every such condition.
Code of Conduct
Environment information
CLI:
Version: 2.5.6
Color support: false
Platform:
CPU Architecture: x86_64
OS: windows
Environment:
BIOME_DISTRIBUTION: npm
BIOME_LOG_PATH: unset
BIOME_LOG_PREFIX_NAME: unset
BIOME_LOG_LEVEL: unset
BIOME_LOG_KIND: unset
BIOME_CONFIG_PATH: unset
BIOME_THREADS: unset
BIOME_WATCHER_KIND: unset
BIOME_WATCHER_POLLING_INTERVAL: unset
NO_COLOR: 1
TERM: unset
JS_RUNTIME_VERSION: v24.16.0
JS_RUNTIME_NAME: node
NODE_PACKAGE_MANAGER: bun/1.3.14
Biome Configuration:
Status: Loaded successfully.
Path: biome.json
Formatter enabled: true
Linter enabled: true
Assist enabled: true
VCS enabled: false
HTML full support enabled: unset
Linter:
JavaScript enabled: unset
JSON enabled: unset
CSS enabled: unset
GraphQL enabled: unset
Recommended: unset
Enabled rules:
suspicious/noUnnecessaryConditions
Workspace:
Open Documents: 0
Rule name
suspicious/noUnnecessaryConditions
Playground link
https://biomejs.dev/playground/?lintRules=all&tab=diagnostics&code=YwBvAG4AcwB0ACAAZwB1AGEAcgBkACAAPQAgAHsAIABjAHUAcgByAGUAbgB0ADoAIABmAGEAbABzAGUAIAB9ADsACgAKAGUAeABwAG8AcgB0ACAAZgB1AG4AYwB0AGkAbwBuACAAcgB1AG4ATwBuAGMAZQAoACkAIAB7AAoACQBpAGYAIAAoAGcAdQBhAHIAZAAuAGMAdQByAHIAZQBuAHQAKQAgAHsACgAJAAkAcgBlAHQAdQByAG4AOwAKAAkAfQAKAAkAZwB1AGEAcgBkAC4AYwB1AHIAcgBlAG4AdAAgAD0AIAB0AHIAdQBlADsACgB9AAoACgAvAC8AIABDAG8AbgB0AHIAbwBsADoAIAB0AGgAZQAgAHMAYQBtAGUAIABsAG8AZwBpAGMAIABvAG4AIABhACAAYgBpAG4AZABpAG4AZwAgAHIAYQB0AGgAZQByACAAdABoAGEAbgAgAGEAIABwAHIAbwBwAGUAcgB0AHkAIABpAHMAIABuAG8AdAAgAGYAbABhAGcAZwBlAGQALgAKAGwAZQB0ACAAZgBsAGEAZwAgAD0AIABmAGEAbABzAGUAOwAKAAoAZQB4AHAAbwByAHQAIABmAHUAbgBjAHQAaQBvAG4AIAByAHUAbgBPAG4AYwBlAEIAaQBuAGQAaQBuAGcAKAApACAAewAKAAkAaQBmACAAKABmAGwAYQBnACkAIAB7AAoACQAJAHIAZQB0AHUAcgBuADsACgAJAH0ACgAJAGYAbABhAGcAIAA9ACAAdAByAHUAZQA7AAoAfQAKAA%3D%3D
Expected result
No diagnostic should be emitted on line 4.
guard.currentis assignedtrueon line 7, so the condition is reachable.Reproduction
biome linton 2.5.6, withsuspicious/noUnnecessaryConditionsas the only enabled rule:Analysis
The property keeps the literal type
falsefrom its initialiser, and the later assignment is not taken into account. The control case in the same file shows the asymmetry: the mutation exemption added in #10108 covers plain bindings, but not member expressions. TypeScript widens the property tobooleanhere and reports nothing.Other shapes that reproduce
const r = useRef(false); … r.current = true— this is the common React in-flight guard against double submission, and it is where I hit the false positive in real code.const r = useRef<boolean>(false)— an explicit type argument does not help; the initialiser still wins.const r = useRef(0); … r.current = 1— same behaviour, reported as always falsy.const r = useRef(true); … r.current = false— reported as always truthy.An
ascast on the initialiser (useRef(false as boolean)) silences it, which is consistent with the literal type being the cause.Impact
The reported code is not redundant, so acting on the diagnostic removes a working guard. There is no safe automatic fix; the only option today is a
biome-ignorecomment on every such condition.Code of Conduct