ajaxorg/ace · error · Error

Can't add a fold to this FoldLine as it has no connection

Error message

Can't add a fold to this FoldLine as it has no connection

What it means

FoldLine.addFold() only accepts a fold whose start/end rows fall within this FoldLine's row span when the fold is sameRow. A fold outside the FoldLine's range means internal fold/bookkeeping state is inconsistent, so Ace throws to prevent corrupting the fold structure.

Source

Thrown at src/edit_session/fold_line.js:53

     * @param {number} shift
     */
    shiftRow(shift) {
        this.start.row += shift;
        this.end.row += shift;
        this.folds.forEach(function(fold) {
            fold.start.row += shift;
            fold.end.row += shift;
        });
    }

    /**
     * @param {Fold} fold
     */
    addFold(fold) {
        if (fold.sameRow) {
            // @ts-expect-error TODO: startRow, endRow are missing in Fold and FoldLine
            if (fold.start.row < this.startRow || fold.endRow > this.endRow) {
                throw new Error("Can't add a fold to this FoldLine as it has no connection");
            }
            this.folds.push(fold);
            this.folds.sort(function(a, b) {
                return -a.range.compareEnd(b.start.row, b.start.column);
            });
            if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {
                this.end.row = fold.end.row;
                this.end.column =  fold.end.column;
            } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {
                this.start.row = fold.start.row;
                this.start.column = fold.start.column;
            }
        } else if (fold.start.row == this.end.row) {
            this.folds.push(fold);
            this.end.row = fold.end.row;
            this.end.column = fold.end.column;
        } else if (fold.end.row == this.start.row) {
            this.folds.unshift(fold);

View on GitHub (pinned to 2c1eddc392)

Solutions

  1. Only add folds via editSession.addFold with a range within a single line, or spanning rows handled by the FoldLine merge logic
  2. Re-fetch/refresh fold structures after external edits rather than caching FoldLine objects
  3. Use the built-in folding mode APIs instead of constructing Fold/FoldLine manually

Example fix

// before
var foldLine = session.foldLines[0];
foldLine.addFold(fold); // fold rows outside foldLine
// after
session.addFold('...', new AceRange(0, 5, 0, 10)); // let session manage FoldLines
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure folds are added through the session, not FoldLine directly
// and check row containment first:
if (fold.start.row < foldLine.startRow || fold.end.row > foldLine.endRow) {
  throw new Error('fold outside fold line');
}

Type guard

function canAddTo(foldLine, fold) { return fold.start.row >= foldLine.startRow && fold.end.row <= foldLine.endRow; }

Try / catch

try { session.addFold('...', range); } catch (e) { if (/no connection|matching row/.test(e.message)) { session.unfold(range, true); session.addFold('...', range); } else throw e; }

Prevention

When it happens

Trigger: Calling editSession.addFold/addUntitledFold with a range that spans rows incorrectly merged, or programmatic fold manipulation while the session's fold lines are stale (e.g. after external edits without proper change notification).

Common situations: Plugins or custom folding code adding folds manually; editing text via low-level APIs that bypass session document change events; merging fold lines during concurrent edits.

Related errors


AI-assisted analysis of ajaxorg/ace@2c1eddc392 (2026-08-30). Data as JSON: /api/errors/dec8346138c89d31. Report an issue: GitHub.