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

  1. Read the wrapped Lua error for the failing script line and fix it
  2. Guard against nil fields in the event table inside the callback
  3. Ensure the callback always returns nil or a table as its final statement
  4. Test the callback in a standalone Lua interpreter with a mock event table
  5. 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

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


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)