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
- Only add folds via editSession.addFold with a range within a single line, or spanning rows handled by the FoldLine merge logic
- Re-fetch/refresh fold structures after external edits rather than caching FoldLine objects
- 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
- Always use editSession.addFold/unfold APIs
- Don't cache FoldLine references across edits
- Unfold before re-folding mutated regions
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.