ajaxorg/ace · error · Error
Mark not set
Error message
Mark not set
What it means
In vim ex command line specs, a mark reference ('x) looks up a previously set mark via getMarkPos. If the named mark was never set (or was invalidated), the position lookup returns null and the parser throws 'Mark not set', mirroring Vim's own behavior.
Source
Thrown at src/keyboard/vim.js:6128
return result;
},
parseLineSpec_: function(cm, inputStream) {
var numberMatch = inputStream.match(/^(\d+)/);
if (numberMatch) {
// Absolute line number plus offset (N+M or N-M) is probably a typo,
// not something the user actually wanted. (NB: vim does allow this.)
return parseInt(numberMatch[1], 10) - 1;
}
switch (inputStream.next()) {
case '.':
return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);
case '$':
return this.parseLineSpecOffset_(inputStream, cm.lastLine());
case '\'':
var markName = inputStream.next();
var markPos = getMarkPos(cm, cm.state.vim, markName);
if (!markPos) throw new Error('Mark not set');
return this.parseLineSpecOffset_(inputStream, markPos.line);
case '-':
case '+':
inputStream.backUp(1);
// Offset is relative to current line if not otherwise specified.
return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);
default:
inputStream.backUp(1);
return undefined;
}
},
parseLineSpecOffset_: function(inputStream, line) {
var offsetMatch = inputStream.match(/^([+-])?(\d+)/);
if (offsetMatch) {
var offset = parseInt(offsetMatch[2], 10);
if (offsetMatch[1] == "-") {
line -= offset;
} else {View on GitHub (pinned to 2c1eddc392)
Solutions
- Set the mark first in normal mode (e.g. ma for mark a)
- Use a different line spec (%, ., $) that doesn't rely on marks
- Guard the command execution with a check that the mark exists
Example fix
// before :’a,’b s/foo/bar/g // marks never set -> throws // after :normal ma // set mark a first :'a,'b s/foo/bar/g
Defensive patterns
Strategy: validation
Validate before calling
// Ensure marks exist before running mark-based ranges
var marksSet = ['a', 'b'].every(function(m) {
return !!window.__getMark && !!window.__getMark(m); // or track marks in your macro runner
});
if (!marksSet) return; // skip command or set marks first Type guard
function markExists(cm, name) { try { return !!cm.ace.session; } catch (e) { return false; } } // verify via editor state before mark-based ranges Try / catch
try { executeEx(":'a,'b s/x/y/g"); } catch (e) { if (/Mark not set/.test(e.message)) { /* set marks or use % range */ } else throw e; } Prevention
- Set marks (ma) before mark-based commands
- Avoid mark ranges in macros for fresh buffers
- Prefer % or absolute line ranges when marks are optional
When it happens
Trigger: Executing an ex range/command using a mark like :'a,'y s/x/y/ when mark 'a' was never set with ma; marks cleared by edits that deleted the marked line.
Common situations: Recording macros or remaps that assume marks exist; running commands on a freshly opened buffer where marks are unset.
Related errors
- (Vim.defineEx) "'+prefix+'" is not a prefix of "'+name+'", c
- Search feature not available. Requires searchcursor.js or an
AI-assisted analysis of ajaxorg/ace@2c1eddc392 (2026-08-30).
Data as JSON: /api/errors/ccb87ed95fcd2b96.
Report an issue: GitHub.