ssssssss-team/spider-flow · error · Error
There is no line " + (n + doc.first) + " in the document.
Error message
There is no line " + (n + doc.first) + " in the document.
What it means
CodeMirror's internal getLine() validates a line number against the document before descending the line-chunk tree. If the number is negative or >= doc.size it throws this error, meaning code asked the document for a line that does not exist.
Solutions
- Clamp/validate the line number against cm.lineCount() (0-based) before use
- Re-fetch line numbers from current positions/handles inside change handlers instead of caching them
- Use CodeMirror.posFromIndex/clipPos to normalize positions into the document
Example fix
// before var line = cm.getLine(savedLine); // after var n = Math.min(savedLine, cm.lineCount() - 1); var line = n >= 0 ? cm.getLine(n) : null;
Defensive patterns
Strategy: validation
Validate before calling
function lineExists(cm, n) {
return Number.isInteger(n) && n >= 0 && n < cm.lineCount();
}
if (!lineExists(cm, n)) return; // or clamp: n = Math.max(0, Math.min(n, cm.lineCount()-1)); Type guard
function isValidLine(doc, n) {
return typeof n === "number" && n >= doc.first && n - doc.first < doc.size;
} Try / catch
try {
var line = cm.getLine(n);
} catch (e) {
if (/no line \d+ in the document/.test(e.message)) {
line = null; // stale index after edit; recompute from cm.posFromIndex or marks
} else { throw e; }
} Prevention
- Remember line numbers are 0-based and bounded by cm.lineCount()-1, not doc.size
- Recompute positions inside change/display events instead of caching indices across edits
- Use cm.clipPos() or posFromIndex() to normalize any external position before use
When it happens
Trigger: Calling editor.getLine(n), doc.getLineHandle(n), getRange/setBookmark/markText/etc. with a line index that is negative, >= doc.lineCount(), or on a document that has since been shrunk by a change event before the index was recomputed.
Common situations: Off-by-one arithmetic (using doc.size instead of lineCount()-1), caching line numbers across asynchronous edits, iterating lines while deletions shrink the document, or plugins passing stale pos.line values.
Related errors
- Mode " + mode.name + " failed to advance stream.
- This document is already in use.
- Inserting collapsed marker partially overlapping an…
- Unrecognized modifier name: " + mod
- Inconsistent bindings for " + name
AI-assisted analysis of ssssssss-team/spider-flow@c799cca99c (2026-09-08).
Data as JSON: /api/errors/57155842880fec80.
Report an issue: GitHub.
Appendix: source
Thrown at spider-flow-web/src/main/resources/static/js/codemirror/codemirror.js:876
StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
StringStream.prototype.hideFirstChars = function (n, inner) {
this.lineStart += n;
try { return inner() }
finally { this.lineStart -= n; }
};
StringStream.prototype.lookAhead = function (n) {
var oracle = this.lineOracle;
return oracle && oracle.lookAhead(n)
};
StringStream.prototype.baseToken = function () {
var oracle = this.lineOracle;
return oracle && oracle.baseToken(this.pos)
};
// Find the line object corresponding to the given line number.
function getLine(doc, n) {
n -= doc.first;
if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") }
var chunk = doc;
while (!chunk.lines) {
for (var i = 0;; ++i) {
var child = chunk.children[i], sz = child.chunkSize();
if (n < sz) { chunk = child; break }
n -= sz;
}
}
return chunk.lines[n]
}
// Get the part of a document between two positions, as an array of
// strings.
function getBetween(doc, start, end) {
var out = [], n = start.line;
doc.iter(start.line, end.line + 1, function (line) {
var text = line.text;
if (n == end.line) { text = text.slice(0, end.ch); }View on GitHub (pinned to c799cca99c)