{"record":{"id":"b24fb8302097ccd7","repo":"micro-editor/micro","slug":"plugin-s-s","errorCode":null,"errorMessage":"Plugin %s: %s","messagePattern":"Plugin (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/plugin.go","lineNumber":36,"sourceCode":"\t\terr := p.Load()\n\t\tif err != nil {\n\t\t\treterr = err\n\t\t}\n\t}\n\treturn reterr\n}\n\n// RunPluginFn runs a given function in all plugins\n// returns an error if any of the plugins had an error\nfunc RunPluginFn(fn string, args ...lua.LValue) error {\n\tvar reterr error\n\tfor _, p := range Plugins {\n\t\tif !p.IsLoaded() {\n\t\t\tcontinue\n\t\t}\n\t\t_, err := p.Call(fn, args...)\n\t\tif err != nil && err != ErrNoSuchFunction {\n\t\t\treterr = errors.New(\"Plugin \" + p.Name + \": \" + err.Error())\n\t\t}\n\t}\n\treturn reterr\n}\n\n// RunPluginFnBool runs a function in all plugins and returns\n// false if any one of them returned false\n// also returns an error if any of the plugins had an error\nfunc RunPluginFnBool(settings map[string]any, fn string, args ...lua.LValue) (bool, error) {\n\tvar reterr error\n\tretbool := true\n\tfor _, p := range Plugins {\n\t\tif !p.IsLoaded() || (settings != nil && settings[p.Name] == false) {\n\t\t\tcontinue\n\t\t}\n\t\tval, err := p.Call(fn, args...)\n\t\tif err == ErrNoSuchFunction {\n\t\t\tcontinue","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/micro-editor/micro/blob/1c8b82b32e408a5faf340039ed92d5266bea3293/internal/config/plugin.go#L18-L54","documentation":"Returned by config.RunPluginFn when any loaded plugin's Lua call to the given hook function returns a runtime error other than ErrNoSuchFunction (which means the plugin simply doesn't define the hook). The error is prefixed with the plugin's name so you know which plugin misbehaved; note only the LAST failing plugin's error is kept.","triggerScenarios":"A plugin's Lua hook (e.g. onBufChange, onToggleKey, onExit) raising a Lua runtime error — indexing a nil global, calling a removed micro API function, bad argument types. p.Call executes the plugin's Lua; any error at internal/config/plugin.go:36 becomes 'Plugin <name>: <lua error>'.","commonSituations":"Plugin written for an older micro Lua API after a micro upgrade (renamed/removed functions), a plugin whose init.lua had runtime issues that only manifest on certain events, or half-updated plugin installs.","solutions":["Read the message: the plugin name and Lua error pinpoint the file/line in the plugin.","Update the plugin: git pull in ~/.config/micro/plug/<name> or reinstall via the plugin manager.","Disable the plugin: set \"plugin name\": false in settings.json (or remove its folder) to unblock your editing session.","If it is your own plugin, fix the Lua: the error text usually contains the Lua source line; test with `micro -config-dir $(mktemp -d)` isolating it."],"exampleFix":"-- before (plugin myplug/init.lua):\nfunction onBufChange(buf) local t = buf[1].x end -- buf[1] nil -> runtime error\n\n-- after:\nfunction onBufChange(buf) if #buf > 0 then local x = buf[1].X end end","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := config.RunPluginFn(\"onBufChange\", lua.LString(\"changed\")); err != nil {\n    if strings.HasPrefix(err.Error(), \"Plugin \") {\n        name := strings.SplitN(strings.TrimPrefix(err.Error(), \"Plugin \"), \":\", 2)[0]\n        // disable offender: config.GlobalSettings[name] = false; log and continue\n    }\n}","preventionTips":["Keep plugins updated; most 'Plugin X:' errors after upgrades are API-drift fixes upstream.","As a plugin author, wrap hook bodies in pcall during development so your errors self-contain.","Maintain a known-good set: pin plugin commits in ~/.config/micro/plug and test before micro upgrades."],"tags":["plugins","lua","runtime-error","hooks"],"backgroundTag":null,"analyzedSha":"1c8b82b32e408a5faf340039ed92d5266bea3293","analyzedAt":"2026-08-15T20:01:45.134Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}