Jguer/yay · error

callback must return nil or a table, got

Error message

callback must return nil or a table, got %s

What it means

parseSearchFilterResult validates the value returned by a search-filter callback: it must be LNil (meaning 'no changes') or an *glua.LTable. Any other type produces this error with the actual Lua type name. This is the entry-point type check before per-entry validation of the returned results table.

Solutions

  1. Return nil to leave the result set unchanged.
  2. Return a plain Lua table (array of {source=..., name=...} entries) — not a string or boolean.
  3. Ensure the callback does not fall through returning the last expression's non-table value; add an explicit `return nil`.

Example fix

-- before
filter = function(active) return true end
-- after
filter = function(active) return nil end  -- or a table of result entries
Defensive patterns

Strategy: validation

Validate before calling

-- Lua: guard the return value in the callback
local out = compute_results()
if out ~= nil and type(out) ~= "table" then out = nil end
return out

Try / catch

refs, _, err := engine.ApplySearchFilter(active)
if err != nil {
    log.Printf("filter returned wrong type (%v); ignoring filter", err)
    refs = nil
}

Prevention

When it happens

Trigger: A search-filter autocmd callback returns a string, number, boolean, or function instead of nil or a table of result entries.

Common situations: Users return `true` to mean 'keep results' instead of nil; they return a comma-joined string of source names; they return a single result table instead of a table containing result tables.

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/3542dbc01202bc9d. Report an issue: GitHub.

Appendix: source

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

		if !isStr {
			return "", false, fmt.Errorf("%s: callback must return a string or nil, got %s", eventName, value.Type())
		}

		rendered = string(str)
		ok = true
	}

	return rendered, ok, nil
}

func parseSearchFilterResult(value glua.LValue, valid map[SearchResultRef]int) ([]SearchResultRef, bool, error) {
	if value == glua.LNil {
		return nil, false, nil
	}

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

	var (
		refs     []SearchResultRef
		parseErr error
	)

	seen := mapset.NewThreadUnsafeSet[SearchResultRef]()

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

		entry, ok := val.(*glua.LTable)
		if !ok {
			parseErr = fmt.Errorf("each result must be a table")
			return

View on GitHub (pinned to 328f4b4939)