{"record":{"id":"79061837cf601ae0","repo":"ajaxorg/ace","slug":"search-feature-not-available-requires-searchcurso","errorCode":null,"errorMessage":"Search feature not available. Requires searchcursor.js or any other getSearchCursor implementation.","messagePattern":"Search feature not available\\. Requires searchcursor\\.js or any other getSearchCursor implementation\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/keyboard/vim.js","lineNumber":6580,"sourceCode":"            var lineHandle = matchedLines[index++];\n            var lineNum = cm.getLineNumber(lineHandle);\n            if (lineNum == null) {\n              nextCommand();\n              return;\n            }\n            var command = (lineNum + 1) + cmd;\n            exCommandDispatcher.processCommand(cm, command, {\n              callback: nextCommand\n            });\n          } else if (cm.releaseLineHandles) {\n            cm.releaseLineHandles();\n          }\n        };\n        nextCommand();\n      },\n      substitute: function(cm, params) {\n        if (!cm.getSearchCursor) {\n          throw new Error('Search feature not available. Requires searchcursor.js or ' +\n              'any other getSearchCursor implementation.');\n        }\n        var argString = params.argString;\n        var tokens = argString ? splitBySeparator(argString, argString[0]) : [];\n        var regexPart, replacePart = '', trailing, flagsPart, count;\n        var confirm = false; // Whether to confirm each replace.\n        var global = false; // True to replace all instances on a line, false to replace only 1.\n        if (tokens.length) {\n          regexPart = tokens[0];\n          if (getOption('pcre') && regexPart !== '') {\n              regexPart = new RegExp(regexPart).source; //normalize not escaped characters\n          }\n          replacePart = tokens[1];\n          if (replacePart !== undefined) {\n            if (getOption('pcre')) {\n              replacePart = unescapeRegexReplace(replacePart.replace(/([^\\\\])&/g,\"$1$$&\"));\n            } else {\n              replacePart = translateRegexReplace(replacePart);","sourceCodeStart":6562,"sourceCodeEnd":6598,"githubUrl":"https://github.com/ajaxorg/ace/blob/2c1eddc392eb92cf222a4478f1893d2b2c354fb0/src/keyboard/vim.js#L6562-L6598","documentation":"The :substitute ex command requires a search cursor implementation (cm.getSearchCursor), normally provided by searchcursor.js. Without it, Ace-vim cannot perform the search/replace and throws instead of silently failing.","triggerScenarios":"Using :s/foo/bar/g in Ace's vim mode without loading ace/ext/searchbox or otherwise having getSearchCursor available on the editor instance; bundling vim.js without its search dependency.","commonSituations":"Custom minimal Ace builds excluding the search extension; lazy-loading vim mode without search support; direct ace.require('ace/keyboard/vim') usage in a stripped bundle.","solutions":["Load the search cursor extension (e.g. include and require 'ace/ext/searchbox' / search support) before using :substitute","Use a full Ace build that includes search dependencies","Fall back to editor.replaceAll(regex, options) API instead of the vim :s command"],"exampleFix":"// before\n// only vim mode loaded, no search support\n:substitute /foo/bar/g\n// after\nace.require('ace/ext/searchbox'); // ensure search cursor available\n// then :%s/foo/bar/g works","handlingStrategy":"validation","validationCode":"if (typeof editor.getSearchCursor !== 'function') {\n  ace.require('ace/ext/searchbox'); // or load a build with search support\n}\n// then run :%s/foo/bar/g","typeGuard":"function hasSearchSupport(cm) { return typeof cm.getSearchCursor === 'function'; }","tryCatchPattern":"try { executeEx(':%s/foo/bar/g'); } catch (e) { if (/Search feature not available/.test(e.message)) { editor.replaceAll('bar', { needle: 'foo' }); } else throw e; }","preventionTips":["Always bundle/require the search extension with vim mode","Use full Ace builds in production","Add a startup assertion that getSearchCursor exists when vim mode is enabled"],"tags":["vim","missing-dependency","search"],"backgroundTag":"missing-dependency","analyzedSha":"2c1eddc392eb92cf222a4478f1893d2b2c354fb0","analyzedAt":"2026-08-30T00:39:52.222Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}