Jguer/yay · error

exclude must be a table

Error message

exclude must be a table

What it means

When the UpgradeSelect callback returns a table, its 'exclude' field must be a table (list of package-name strings); a scalar 'exclude' value produces 'exclude must be a table'. The library throws this to reject malformed hook results rather than guessing the intent.

Solutions

  1. Wrap the value in a table: exclude = { 'pkg1', 'pkg2' }
  2. Use an empty table exclude = {} if nothing should be excluded
  3. Omit the exclude key entirely when not needed
  4. Verify the variable holding the exclude list is actually a table (type(x) == 'table')

Example fix

-- before
return { exclude = 'linux-kernel' }
-- after
return { exclude = { 'linux-kernel' } }
Defensive patterns

Strategy: validation

Validate before calling

local r = myUpgradeSelect(mockEvent)
assert(r == nil or r.exclude == nil or type(r.exclude) == 'table', 'exclude must be a table')

Type guard

local function hasListExclude(r) return r == nil or r.exclude == nil or type(r.exclude) == 'table' end

Prevention

When it happens

Trigger: Callback returns { exclude = <non-table> } — e.g. exclude = 'linux', exclude = 42, or exclude = true.

Common situations: Passing a single package name as a string instead of a list; Lua config built by string concatenation producing the wrong type; misunderstanding that exclude is a set-like table of names.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of Jguer/yay@328f4b4939 (2026-09-07). Data as JSON: /api/errors/702afdf7a428a1f6. Report an issue: GitHub.

Appendix: source

Thrown at pkg/settings/lua/autocmd.go:367

	return tbl
}

func (e *Engine) parseUpgradeSelectResult(value glua.LValue, validExcludes mapset.Set[string]) (UpgradeSelectResult, error) {
	var result UpgradeSelectResult
	if value == glua.LNil {
		return result, nil
	}

	tbl, ok := value.(*glua.LTable)
	if !ok {
		return result, fmt.Errorf("callback must return nil or table, got %s", value.Type())
	}

	if excludeValue := tbl.RawGetString("exclude"); excludeValue != glua.LNil {
		excludeTbl, ok := excludeValue.(*glua.LTable)
		if !ok {
			return result, fmt.Errorf("exclude must be a table")
		}

		var parseErr error
		excludeTbl.ForEach(func(_ glua.LValue, val glua.LValue) {
			if parseErr != nil {
				return
			}

			lname, ok := val.(glua.LString)
			if !ok {
				parseErr = fmt.Errorf("exclude entries must be strings")
				return
			}

			name := string(lname)
			if !validExcludes.Contains(name) {
				parseErr = fmt.Errorf("unknown upgrade exclusion %q", name)
				return

View on GitHub (pinned to 328f4b4939)