oxc-project/oxc · warning · OxcDiagnostic
Block is unnecessary.
Error message
Block is unnecessary.
What it means
Diagnostic from oxlint's eslint/no-lone-blocks rule (crates/oxc_linter/src/rules/eslint/no_lone_blocks.rs:10). It reports a standalone block statement '{ ... }' that serves no purpose: it does not create a scope that matters unless it contains let/const/class/function declarations (per modern ESLint semantics, blocks containing such lexical declarations are 'necessary' and not reported). Leftover braces from deleted if/try statements are the classic source.
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_lone_blocks.rs:10
use oxc_ast::AstKind;
use oxc_ast::ast::{Declaration, VariableDeclarationKind};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, rule::Rule};
fn no_lone_blocks_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Block is unnecessary.")
.with_help("Remove the unnecessary block statement. If you need to limit variable scope, consider using a function or module instead.")
.with_label(span)
}
fn no_nested_lone_blocks_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Nested block is redundant.")
.with_help("Remove the redundant nested block statement.")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoLoneBlocks;
declare_oxc_lint!(
/// ### What it does
///
/// Disallows unnecessary standalone block statements.
///View on GitHub (pinned to e1e7af627c)
Solutions
- Remove the braces and keep the inner statements, dedenting them
- If the block was used for scope, replace it with an IIFE or move the code into a function (or use let/const for real block scoping)
- Check for accidentally deleted control-flow keywords above the block (if/else/for/while) and restore them if the braces were meant to belong to one
Example fix
// before
{
var x = 1;
console.log(x);
}
// after
var x = 1;
console.log(x); Defensive patterns
Strategy: validation
Prevention
- When deleting an if/for/try, delete both its keyword and its braces in one edit
- Use let/const (real block scoping) instead of bare blocks plus var
- Run a formatter/linter on save so leftover braces are flagged immediately
When it happens
Trigger: A block statement not attached to if/for/while/try/function that contains only statements using var or expressions: '{ doWork(); }' at top level or inside another block; braces left after removing an 'if (debug)' wrapper.
Common situations: Deleting an if/for/try line but leaving its braces; old scoping hacks from pre-ES2015 code that used blocks + var for 'namespacing'; merging code where a block was used to avoid variable name clashes that no longer exist.
Related errors
- Nested block is redundant.
- Duplicate class member: {member_name:?}
- Duplicate conditions in if-else-if chain
- Duplicate key '{key}'
- Duplicate case label
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/9e4f55652387cd14.
Report an issue: GitHub.