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

  1. Clamp/validate the line number against cm.lineCount() (0-based) before use
  2. Re-fetch line numbers from current positions/handles inside change handlers instead of caching them
  3. 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

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


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)