{"record":{"id":"4bd40d3fcf514a9d","repo":"oxc-project/oxc","slug":"disallow-non-null-assertions-in-the-left-operand","errorCode":null,"errorMessage":"'Disallow non-null assertions in the left operand of a nullish coalescing operator","messagePattern":"'Disallow non-null assertions in the left operand of a nullish coalescing operator","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/typescript/no_non_null_asserted_nullish_coalescing.rs","lineNumber":15,"sourceCode":"use oxc_ast::{AstKind, ast::Expression};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::SymbolId;\nuse oxc_span::Span;\nuse oxc_syntax::operator::LogicalOperator;\n\nuse crate::{\n    AstNode,\n    context::{ContextHost, LintContext},\n    rule::Rule,\n};\n\nfn no_non_null_asserted_nullish_coalescing_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"'Disallow non-null assertions in the left operand of a nullish coalescing operator\")\n        .with_help(\"The nullish coalescing operator is designed to handle undefined and null - using a non-null assertion is not needed.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoNonNullAssertedNullishCoalescing;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow non-null assertions in the left operand of a nullish coalescing operator.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// The ?? nullish coalescing runtime operator allows providing a default value when dealing\n    /// with `null` or `undefined`. Using a ! non-null assertion type operator in the left operand of\n    /// a nullish coalescing operator is redundant, and likely a sign of programmer error or\n    /// confusion over the two operators.","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_nullish_coalescing.rs#L1-L33","documentation":"Oxlint's no-non-null-asserted-nullish-coalescing: `left! ?? right` first asserts the left operand is never null or undefined, then coalesces on nullish values, which is contradictory. The help at no_non_null_asserted_nullish_coalescing.rs:19 notes that `??` exists precisely to handle undefined and null, so the assertion is unnecessary. (The message string in this version literally begins with a stray apostrophe; that is a cosmetic typo in the source, not part of your code.)","triggerScenarios":"`foo! ?? 'default'`, `(a.b)! ?? c` - a TSNonNullAssertion as the left operand of a nullish coalescing operator (LogicalOperator::Coalesce).","commonSituations":"Developers silencing 'possibly undefined' errors on the left of `??`; refactors where an assertion and a default were bolted on at different times.","solutions":["Remove the `!` and let `??` handle the nullish case","If the value truly cannot be nullish, remove the `??` instead","Use an explicit undefined check before the expression"],"exampleFix":"// before\nconst port = config.port! ?? 8080;\n\n// after\nconst port = config.port ?? 8080;","handlingStrategy":"validation","validationCode":"npx oxlint --deny-warnings .","typeGuard":"function isDefined<T>(value: T | null | undefined): value is T {\n  return value !== null && value !== undefined;\n}","tryCatchPattern":null,"preventionTips":["Pick one: either trust `??` to handle nullish, or assert and drop the `??`","Search for `! ??` in review diffs; the combination is always contradictory","Enable the rule in the editor to catch it at typing time"],"tags":["typescript","lint","non-null-assertion","nullish-coalescing"],"backgroundTag":"nullish-coalescing-non-null-assertion","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}