Jguer/yay · error
%s: %w
Error message
%s: %w
What it means
RunUpgradeSelect calls registered 'UpgradeSelect' autocmd callbacks expecting 1 return value; if the Lua call itself fails (script error, abort), the result is wrapped as 'UpgradeSelect: <lua error>'. This means yay could not obtain a valid upgrade-selection decision from the user script. wrapLuaErr strips gopher-lua internals from the message.
Solutions
- Read the wrapped Lua error for the failing script line and fix it
- Guard against nil fields in the event table inside the callback
- Ensure the callback always returns nil or a table as its final statement
- Test the callback in a standalone Lua interpreter with a mock event table
- Remove/neutralize the autocmd to proceed without script-driven selection
Example fix
-- before
autocmd('UpgradeSelect', function(e) return { exclude = filter(e.packages) } end)
-- after
autocmd('UpgradeSelect', function(e)
if not e or not e.packages then return nil end
return { exclude = filter(e.packages) }
end) Defensive patterns
Strategy: try-catch
Validate before calling
-- verify the callback returns a table or nil
local ok, res = pcall(myUpgradeSelect, mockEvent)
if not ok then error('hook errors: ' .. tostring(res)) end
assert(res == nil or type(res) == 'table', 'must return nil or table') Try / catch
result, err := engine.RunUpgradeSelect(event, validExcludes)
if err != nil {
log.Warnf("UpgradeSelect hook failed (%v); using default selection", err)
result = defaultSelection
} Prevention
- Always end every code path of the callback with `return nil` or a table
- Wrap the callback body in pcall and return nil on failure
- Test the hook against a mock event before enabling it
When it happens
Trigger: An UpgradeSelect autocmd callback raises a Lua error during its protected call (CallByParam with NRet=1) before a return value can be parsed — e.g. calling a nil function, indexing a nil event field, or calling abort().
Common situations: User config with a buggy UpgradeSelect hook; script assumes fields on the event table that don't exist in the installed yay version; Lua stdlib function misuse (string.format with wrong args).
Related errors
- %s %s: %w
- : callback must return a string or nil, got
- callback must return nil or table, got
- exclude must be a table
- exclude entries must be strings
AI-assisted analysis of Jguer/yay@328f4b4939 (2026-09-07).
Data as JSON: /api/errors/7e901258015b33ed.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/settings/lua/autocmd.go:228
func (e *Engine) RunUpgradeSelect(event *UpgradeSelectEvent) (UpgradeSelectResult, error) {
var result UpgradeSelectResult
if !e.HasAutocmd(EventUpgradeSelect) {
return result, nil
}
validExcludes := mapset.NewThreadUnsafeSetWithSize[string](len(event.Upgrades))
for i := range event.Upgrades {
validExcludes.Add(event.Upgrades[i].Name)
}
seenExcludes := mapset.NewThreadUnsafeSet[string]()
for _, autocmd := range e.autocmds[EventUpgradeSelect] {
if err := e.L.CallByParam(glua.P{
Fn: autocmd.callback,
NRet: 1,
Protect: true,
}, e.upgradeSelectTable(event)); err != nil {
return result, fmt.Errorf("%s: %w", EventUpgradeSelect, wrapLuaErr(err))
}
value := e.L.Get(-1)
e.L.Pop(1)
hookResult, err := e.parseUpgradeSelectResult(value, validExcludes)
if err != nil {
return result, fmt.Errorf("%s: %w", EventUpgradeSelect, err)
}
for _, name := range hookResult.Exclude {
if !seenExcludes.Add(name) {
continue
}
result.Exclude = append(result.Exclude, name)
}
if hookResult.SkipMenu {View on GitHub (pinned to 328f4b4939)