{"record":{"id":"b35ac3e5958b181c","repo":"ssssssss-team/spider-flow","slug":"mode-mode-name-failed-to-advance-stream","errorCode":null,"errorMessage":"Mode \" + mode.name + \" failed to advance stream.","messagePattern":"Mode \" \\+ mode\\.name \\+ \" failed to advance stream\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"spider-flow-web/src/main/resources/static/js/codemirror/codemirror.js","lineNumber":1156,"sourceCode":"      readToken(mode, stream, context.state);\n      stream.start = stream.pos;\n    }\n  }\n\n  function callBlankLine(mode, state) {\n    if (mode.blankLine) { return mode.blankLine(state) }\n    if (!mode.innerMode) { return }\n    var inner = innerMode(mode, state);\n    if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }\n  }\n\n  function readToken(mode, stream, state, inner) {\n    for (var i = 0; i < 10; i++) {\n      if (inner) { inner[0] = innerMode(mode, state).mode; }\n      var style = mode.token(stream, state);\n      if (stream.pos > stream.start) { return style }\n    }\n    throw new Error(\"Mode \" + mode.name + \" failed to advance stream.\")\n  }\n\n  var Token = function(stream, type, state) {\n    this.start = stream.start; this.end = stream.pos;\n    this.string = stream.current();\n    this.type = type || null;\n    this.state = state;\n  };\n\n  // Utility for getTokenAt and getLineTokens\n  function takeToken(cm, pos, precise, asArray) {\n    var doc = cm.doc, mode = doc.mode, style;\n    pos = clipPos(doc, pos);\n    var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise);\n    var stream = new StringStream(line.text, cm.options.tabSize, context), tokens;\n    if (asArray) { tokens = []; }\n    while ((asArray || stream.pos < pos.ch) && !stream.eol()) {\n      stream.start = stream.pos;","sourceCodeStart":1138,"sourceCodeEnd":1174,"githubUrl":"https://github.com/ssssssss-team/spider-flow/blob/c799cca99c7d064673dc79e6ef06a08bbc0e292d/spider-flow-web/src/main/resources/static/js/codemirror/codemirror.js#L1138-L1174","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the mode's token() so every code path either advances the stream (stream.next(), stream.match non-empty) or returns null","Check regexes in the mode for zero-width matches and anchor/skip empty tokens","Bump to a fixed version of the third-party mode or pin a known-good CodeMirror release"],"exampleFix":"// before\nif (stream.match(\"//\")) { stream.skipToEnd(); }\nreturn \"comment\"; // returns even when nothing matched\n// after\nif (stream.eatSpace()) { return null; }\nif (stream.match(\"//\")) { stream.skipToEnd(); return \"comment\"; }\nstream.next();\nreturn null;","handlingStrategy":"try-catch","validationCode":"function modeAdvances(mode, sampleText) {\n  try {\n    var state = mode.startState ? mode.startState() : null;\n    var stream = new CodeMirror.StringStream(sampleText);\n    var before = stream.pos;\n    mode.token(stream, state);\n    return stream.pos > before || stream.eol();\n  } catch (e) { return false; }\n}\nif (!modeAdvances(mode, sample)) console.warn(\"mode never advances\");","typeGuard":"function isStatelessUsableMode(mode) {\n  return mode && typeof mode.token === \"function\";\n}","tryCatchPattern":"try {\n  cm.setOption(\"mode\", suspectMode);\n} catch (e) {\n  if (/failed to advance stream/.test(e.message)) {\n    cm.setOption(\"mode\", \"null\"); // fall back to plain text\n  } else { throw e; }\n}","preventionTips":["Test custom modes with StringStream on edge-case inputs (empty strings, EOF, unicode)","Never return a truthy style without advancing the stream; skip spaces with stream.eatSpace() and return null","Avoid zero-width regex matches (e.g. /x*/) in mode tokenizers","Pin third-party modes to versions tested against your CodeMirror version"],"tags":["codemirror","syntax-highlighting","mode"],"backgroundTag":"internal-invariant-violation","analyzedSha":"c799cca99c7d064673dc79e6ef06a08bbc0e292d","analyzedAt":"2026-09-08T13:47:08.225Z","contentChangedAt":"2026-09-08T13:47:08.225Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}