ssssssss-team/spider-flow · error · Error

Mode " + mode.name + " failed to advance stream.

Error message

Mode " + mode.name + " failed to advance stream.

What it means

CodeMirror calls a mode's token() function up to 10 times, expecting each call to consume at least one character (stream.pos > stream.start). A mode that repeatedly consumes nothing indicates a broken or stuck highlighting mode, so CodeMirror throws to avoid an infinite loop.

Solutions

  1. Fix the mode's token() so every code path either advances the stream (stream.next(), stream.match non-empty) or returns null
  2. Check regexes in the mode for zero-width matches and anchor/skip empty tokens
  3. Bump to a fixed version of the third-party mode or pin a known-good CodeMirror release

Example fix

// before
if (stream.match("//")) { stream.skipToEnd(); }
return "comment"; // returns even when nothing matched
// after
if (stream.eatSpace()) { return null; }
if (stream.match("//")) { stream.skipToEnd(); return "comment"; }
stream.next();
return null;
Defensive patterns

Strategy: try-catch

Validate before calling

function modeAdvances(mode, sampleText) {
  try {
    var state = mode.startState ? mode.startState() : null;
    var stream = new CodeMirror.StringStream(sampleText);
    var before = stream.pos;
    mode.token(stream, state);
    return stream.pos > before || stream.eol();
  } catch (e) { return false; }
}
if (!modeAdvances(mode, sample)) console.warn("mode never advances");

Type guard

function isStatelessUsableMode(mode) {
  return mode && typeof mode.token === "function";
}

Try / catch

try {
  cm.setOption("mode", suspectMode);
} catch (e) {
  if (/failed to advance stream/.test(e.message)) {
    cm.setOption("mode", "null"); // fall back to plain text
  } else { throw e; }
}

Prevention

When it happens

Trigger: Installing a custom or third-party CodeMirror mode whose token() returns a style without advancing the stream (e.g. forgetting stream.next(), or a regex that matches the empty string), or a mode buggy on a specific input token.

Common situations: Custom language modes copied from older CodeMirror versions, modes with zero-length regex matches, or modes applied via {name: ...} config to content they don't handle.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of ssssssss-team/spider-flow@c799cca99c (2026-09-08). Data as JSON: /api/errors/b35ac3e5958b181c. Report an issue: GitHub.

Appendix: source

Thrown at spider-flow-web/src/main/resources/static/js/codemirror/codemirror.js:1156

      readToken(mode, stream, context.state);
      stream.start = stream.pos;
    }
  }

  function callBlankLine(mode, state) {
    if (mode.blankLine) { return mode.blankLine(state) }
    if (!mode.innerMode) { return }
    var inner = innerMode(mode, state);
    if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }
  }

  function readToken(mode, stream, state, inner) {
    for (var i = 0; i < 10; i++) {
      if (inner) { inner[0] = innerMode(mode, state).mode; }
      var style = mode.token(stream, state);
      if (stream.pos > stream.start) { return style }
    }
    throw new Error("Mode " + mode.name + " failed to advance stream.")
  }

  var Token = function(stream, type, state) {
    this.start = stream.start; this.end = stream.pos;
    this.string = stream.current();
    this.type = type || null;
    this.state = state;
  };

  // Utility for getTokenAt and getLineTokens
  function takeToken(cm, pos, precise, asArray) {
    var doc = cm.doc, mode = doc.mode, style;
    pos = clipPos(doc, pos);
    var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise);
    var stream = new StringStream(line.text, cm.options.tabSize, context), tokens;
    if (asArray) { tokens = []; }
    while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
      stream.start = stream.pos;

View on GitHub (pinned to c799cca99c)