can1357/oh-my-pi · warning · Error
spelling range start is too large
Error message
spelling range start is too large
What it means
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.
Source
Thrown at crates/pi-natives/src/spelling.rs:85
where
T: Send + 'static,
{
let (reply, result) = flume::bounded(1);
SPELLING_THREAD
.send(Box::new(move || {
let _ = reply.send(work());
}))
.map_err(|_| Error::new(Status::GenericFailure, "native spelling thread stopped"))?;
result
.recv_async()
.await
.map_err(|_| Error::new(Status::GenericFailure, "native spelling thread stopped"))?
}
fn ns_range(start: u32, length: u32) -> Result<NSRange> {
Ok(NSRange {
location: usize::try_from(start)
.map_err(|_| Error::new(Status::InvalidArg, "spelling range start is too large"))?,
length: usize::try_from(length)
.map_err(|_| Error::new(Status::InvalidArg, "spelling range length is too large"))?,
})
}
pub fn check(text: &str) -> Result<Vec<SpellingRange>> {
let checker = checker()?;
let text = NSString::from_str(text);
let full = NSRange { location: 0, length: text.length() };
// `checkString:...` honors `automaticallyIdentifiesLanguages`, selecting
// the dictionary per detected run; the legacy `checkSpellingOfString:`
// used only the shared checker's single current language (issue #9334).
// SAFETY: `options`/`orthography` are nil and `word_count` is null, all
// documented as valid; the returned array is retained by objc2.
let results = unsafe {
checker.checkString_range_types_options_inSpellDocumentWithTag_orthography_wordCount(
&text,
full,View on GitHub (pinned to 9690622007)
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
Example fix
// before native.checkSpelling(text, startOffset, len); // after const safeStart = Math.min(startOffset >>> 0, text.length); native.checkSpelling(text, safeStart, len);
Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isSafeInteger(start) || start < 0 || start > text.length) throw new RangeError('start out of range'); Type guard
const isValidStart = (s) => Number.isInteger(s) && s >= 0 && s <= 0xFFFFFFFF;
Try / catch
try {
return await native.checkSpelling(text, start, len);
} catch (err) {
if (String(err?.message).includes('spelling range start is too large')) {
throw new RangeError(`spelling start ${start} rejected`);
} throw err;
} Prevention
- Clamp offsets to the text length before calling
- Use 64-bit builds of the native module
- Treat u32 as the maximum valid offset
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- spelling range length is too large
- err.to_string() (size parse error)
- size is too large: {value}
- number of -bytes or -lines is too large
- failed to initialize AppKit
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e2e21a32238df99b.
Report an issue: GitHub.