{"record":{"id":"e2e21a32238df99b","repo":"can1357/oh-my-pi","slug":"spelling-range-start-is-too-large","errorCode":null,"errorMessage":"spelling range start is too large","messagePattern":"spelling range start is too large","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"crates/pi-natives/src/spelling.rs","lineNumber":85,"sourceCode":"\twhere\n\t\tT: Send + 'static,\n\t{\n\t\tlet (reply, result) = flume::bounded(1);\n\t\tSPELLING_THREAD\n\t\t\t.send(Box::new(move || {\n\t\t\t\tlet _ = reply.send(work());\n\t\t\t}))\n\t\t\t.map_err(|_| Error::new(Status::GenericFailure, \"native spelling thread stopped\"))?;\n\t\tresult\n\t\t\t.recv_async()\n\t\t\t.await\n\t\t\t.map_err(|_| Error::new(Status::GenericFailure, \"native spelling thread stopped\"))?\n\t}\n\n\tfn ns_range(start: u32, length: u32) -> Result<NSRange> {\n\t\tOk(NSRange {\n\t\t\tlocation: usize::try_from(start)\n\t\t\t\t.map_err(|_| Error::new(Status::InvalidArg, \"spelling range start is too large\"))?,\n\t\t\tlength:   usize::try_from(length)\n\t\t\t\t.map_err(|_| Error::new(Status::InvalidArg, \"spelling range length is too large\"))?,\n\t\t})\n\t}\n\n\tpub fn check(text: &str) -> Result<Vec<SpellingRange>> {\n\t\tlet checker = checker()?;\n\t\tlet text = NSString::from_str(text);\n\t\tlet full = NSRange { location: 0, length: text.length() };\n\t\t// `checkString:...` honors `automaticallyIdentifiesLanguages`, selecting\n\t\t// the dictionary per detected run; the legacy `checkSpellingOfString:`\n\t\t// used only the shared checker's single current language (issue #9334).\n\t\t// SAFETY: `options`/`orthography` are nil and `word_count` is null, all\n\t\t// documented as valid; the returned array is retained by objc2.\n\t\tlet results = unsafe {\n\t\t\tchecker.checkString_range_types_options_inSpellDocumentWithTag_orthography_wordCount(\n\t\t\t\t&text,\n\t\t\t\tfull,","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-natives/src/spelling.rs#L67-L103","documentation":"The spelling API converts a JS-provided u32 range start to Rust's usize for NSRange. This InvalidArg error is thrown when the start offset cannot be represented as usize on the current platform. On 64-bit macOS usize is 64-bit so a u32 always fits; the error exists to keep the conversion total and is effectively unreachable in normal 64-bit builds.","triggerScenarios":"Calling a spelling API that takes a range (e.g. checkSpelling(text, start, length)) with a start offset whose usize conversion fails — only conceivable on a 32-bit target with start near u32::MAX, or via the internal ns_range helper receiving an out-of-contract value.","commonSituations":"Practically never hit by developers; would appear only in 32-bit native builds or with caller-computed offsets overflowing at the u32 boundary on a 32-bit process.","solutions":["Verify the start offset is a valid index within the text being checked","Ensure you are running a 64-bit build of the native module","Clamp the range start to the text length before calling"],"exampleFix":"// before\nnative.checkSpelling(text, startOffset, len);\n// after\nconst safeStart = Math.min(startOffset >>> 0, text.length);\nnative.checkSpelling(text, safeStart, len);","handlingStrategy":"validation","validationCode":"if (!Number.isSafeInteger(start) || start < 0 || start > text.length) throw new RangeError('start out of range');","typeGuard":"const isValidStart = (s) => Number.isInteger(s) && s >= 0 && s <= 0xFFFFFFFF;","tryCatchPattern":"try {\n  return await native.checkSpelling(text, start, len);\n} catch (err) {\n  if (String(err?.message).includes('spelling range start is too large')) {\n    throw new RangeError(`spelling start ${start} rejected`);\n  } throw err;\n}","preventionTips":["Clamp offsets to the text length before calling","Use 64-bit builds of the native module","Treat u32 as the maximum valid offset"],"tags":["native","macos","range","integer-overflow"],"backgroundTag":"range-offset-out-of-bounds","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}