{"record":{"id":"26ba11daf2d443f7","repo":"oxc-project/oxc","slug":"passing-length-as-the-end-argument-of-a-slice","errorCode":null,"errorMessage":"Passing `length` as the end argument of a `slice` call is unnecessary.","messagePattern":"Passing `length` as the end argument of a `slice` call is unnecessary\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/unicorn/no_length_as_slice_end.rs","lineNumber":14,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{Argument, Expression, MemberExpression},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{\n    AstNode, ast_util::is_method_call, context::LintContext, rule::Rule, utils::is_same_expression,\n};\n\nfn no_length_as_slice_end_diagnostic(call_span: Span, arg_span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Passing `length` as the end argument of a `slice` call is unnecessary.\")\n        .with_help(\"Remove the second argument.\")\n        .with_labels([\n            call_span.label(\"`.slice` called here.\"),\n            arg_span.label(\"Invalid argument here\"),\n        ])\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoLengthAsSliceEnd;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow using `length` as the end argument of a `slice` call.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Passing `length` as the end argument of a `slice` call is unnecessary and can be confusing.","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/unicorn/no_length_as_slice_end.rs#L1-L32","documentation":"Diagnostic from the oxlint rule `unicorn/no-length-as-slice-end`. For `slice(start, end)`, an end at or beyond the receiver's length behaves exactly like omitting the end argument. Passing the receiver's own `.length` (the rule proves the index expression is identical to the call receiver) is redundant noise; the fix is to delete the second argument. `otherArray.length` is not flagged because it may differ.","triggerScenarios":"`items.slice(0, items.length)`, `text.slice(0, text.length)`, `state.rows.slice(from, state.rows.length)` — the second argument is a static `.length` member on an expression identical to the slice receiver. A `.length` of a different object, or `slice(0, n)`, passes.","commonSituations":"Defensive copies written by developers unsure whether slice needs an end; ported Java-style `substring(0, n)` habits; generated or template-produced code.","solutions":["Remove the second argument: `const copy = items.slice(0)`","When copying is the only intent, use `const copy = [...items]` (deep copies need structuredClone)","Suppress inline only in the rare case where the matched length is coincidental and documented"],"exampleFix":"// before\nconst copy = items.slice(0, items.length);\n\n// after\nconst copy = items.slice(0);","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["`slice(start)` already runs to the end — omit the second argument","Use [...arr] for shallow copies and structuredClone for deep copies","Treat `slice(0, x.length)` in review as a sign of uncertainty about slice semantics"],"tags":["arrays","strings","redundant-code","style","oxlint"],"backgroundTag":"redundant-slice-arguments","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}