vitest-dev/vitest · error · Error
offset is longer than source length! offset ${offset} > leng
Error message
offset is longer than source length! offset ${offset} > length ${source.length} What it means
Thrown by offsetToLineNumber() in packages/utils/src/offset.ts when the requested character offset exceeds the source string length. offsetToLineNumber is used to map a character index back to a 1-based line number for diagnostics, inline snapshot placement, and stack-trace rendering. An out-of-range offset means the caller computed the offset against a different (longer) version of the source than the one passed in — typically a stale cache or a transform mismatch.
Source
Thrown at packages/utils/src/offset.ts:25
): number {
const lines = source.split(lineSplitRE)
const nl = /\r\n/.test(source) ? 2 : 1
let start = 0
if (lineNumber > lines.length) {
return source.length
}
for (let i = 0; i < lineNumber - 1; i++) {
start += lines[i].length + nl
}
return start + columnNumber
}
export function offsetToLineNumber(source: string, offset: number): number {
if (offset > source.length) {
throw new Error(
`offset is longer than source length! offset ${offset} > length ${source.length}`,
)
}
const lines = source.split(lineSplitRE)
const nl = /\r\n/.test(source) ? 2 : 1
let counted = 0
let line = 0
for (; line < lines.length; line++) {
const lineLength = lines[line].length + nl
if (counted + lineLength >= offset) {
break
}
counted += lineLength
}
return line + 1
}
View on GitHub (pinned to d568f8ce37)
Solutions
- Clear Vitest/Vite caches (rm -rf node_modules/.vite node_modules/.vitest) and re-run.
- Ensure the source string passed to offsetToLineNumber is the same artifact used to compute the offset.
- If implementing a custom SnapshotEnvironment or transformer, guarantee readSnapshotFile returns stable content.
- Update @vitest/utils and vitest to matching versions; mismatched versions across the monorepo cause this.
Defensive patterns
Strategy: validation
Validate before calling
function assertOffsetInRange(source: string, offset: number): void {
if (offset > source.length) {
throw new RangeError(`offset ${offset} exceeds source length ${source.length}`)
}
} Type guard
const offsetInRange = (source: string, offset: number): boolean => offset >= 0 && offset <= source.length
Prevention
- Always compute offsets and call offsetToLineNumber with the same source string instance.
- Clear node_modules/.vite and node_modules/.vitest after upgrades to avoid stale caches.
- Keep @vitest/utils and vitest on matching versions across the monorepo.
When it happens
Trigger: Source-map or inline-snapshot code computes an offset from the transformed code but passes the original (shorter) source; a custom SnapshotEnvironment returns a different file content on consecutive reads; instrumentation that mutates the source between offset calculation and line lookup.
Common situations: Source-map mismatches after a Vite/Rollup upgrade; cache invalidation issues (.vite cache stale); concurrent edits during watch mode; custom transformers that change file length without updating the source map.
Related errors
- @vitest/snapshot: Couldn't infer stack frame for inline snap
- value of unknown type: ${value}
- ${name} value must be ${types.join(' or ')}, received "${rec
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/90e63c16be911a45.json.
Report an issue: GitHub.