Jguer/yay · error

each result must be a table

Error message

each result must be a table

What it means

While iterating the table returned by a search-filter callback, each element must itself be a table describing one result. When an element is a non-table value (string, number, etc.), the ForEach loop records this error into parseErr, which the caller then wraps with the event name (error 51).

Solutions

  1. Wrap each returned item in a table: { source = "...", name = "..." }.
  2. Only include entries for results you want to keep, drawn from the active result set.
  3. Check the error wrapping to confirm it is the element-type failure rather than the source/name field failures.

Example fix

-- before
return { "bufferlines", "symbols" }
-- after
return { { source = "bufferlines", name = "bufferlines" }, { source = "symbols", name = "symbols" } }
Defensive patterns

Strategy: type-guard

Validate before calling

-- Lua: filter out non-table entries before returning
local entries = {}
for _, e in ipairs(raw) do
  if type(e) == "table" then entries[#entries+1] = e end
end
return entries

Type guard

function is_result_entry(v) return type(v) == "table" and type(v.source) == "string" and type(v.name) == "string" end

Try / catch

if err != nil && strings.Contains(err.Error(), "each result must be a table") {
    log.Print("filter returned non-table entries; check return shape")
}

Prevention

When it happens

Trigger: The callback returns an array of strings/numbers such as {'bufferlines', 'symbols'} instead of an array of tables with source/name keys.

Common situations: Users model results as a flat list of names because other filter APIs accept plain string lists; they pass through the active table's keys instead of building result entries.

Related errors


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

Appendix: source

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

	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
		}

		source, ok := entry.RawGetString("source").(glua.LString)
		if !ok {
			parseErr = fmt.Errorf("result source must be a string")
			return
		}

		name, ok := entry.RawGetString("name").(glua.LString)
		if !ok {
			parseErr = fmt.Errorf("result name must be a string")
			return
		}

		ref := SearchResultRef{Source: string(source), Name: string(name)}
		if _, exists := valid[ref]; !exists {
			parseErr = fmt.Errorf("unknown search result %s/%s", ref.Source, ref.Name)

View on GitHub (pinned to 328f4b4939)