ajaxorg/ace · error · Error

Trying to add fold to FoldRow that doesn't have a matching…

Error message

Trying to add fold to FoldRow that doesn't have a matching row

What it means

FoldLine.addFold() places a fold either at the end of the line (start.row == endRow), at the start (end.row == startRow), or as sameRow. A fold whose rows match none of these cannot belong to this FoldLine, so Ace throws to protect fold integrity.

Solutions

  1. Ensure fold ranges align with FoldLine boundaries (single row, or start/end matching the FoldLine's rows)
  2. Use editSession.addFold / unfold APIs rather than manipulating FoldLine directly
  3. Unfold and re-fold the region if line numbers shifted after edits

Example fix

// before
foldLine.addFold(new Fold(3, 0, 7, 5)); // spans beyond this fold line
// after
session.addFold('...', new AceRange(3, 0, 7, 5));
Defensive patterns

Strategy: try-catch

Validate before calling

if (!(fold.end.row === foldLine.start.row || fold.start.row === foldLine.endRow || (fold.start.row === fold.end.row && fold.start.row >= foldLine.startRow && fold.end.row <= foldLine.endRow))) {
  throw new Error('fold rows do not align with FoldLine');
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Adding a fold whose row range partially overlaps a fold line (e.g. fold from row 3 to row 7 on a FoldLine covering rows 2-4); manually constructing folds across multiple FoldLines.

Common situations: Custom folding plugins computing ranges incorrectly; folding operations applied after text changed line numbers without updating fold state.

Related errors


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

Appendix: source

Thrown at src/edit_session/fold_line.js:75

                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);
            this.start.row = fold.start.row;
            this.start.column = fold.start.column;
        } else {
            throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");
        }
        fold.foldLine = this;
    }

    /**
     * @param {number} row
     */
    containsRow(row) {
        return row >= this.start.row && row <= this.end.row;
    }

    /**
     * @param {Function} callback
     * @param {number} endRow
     * @param {number} endColumn
     */
    walk(callback, endRow, endColumn) {
        var lastEnd = 0,

View on GitHub (pinned to 2c1eddc392)