{"record":{"id":"3542dbc01202bc9d","repo":"Jguer/yay","slug":"callback-must-return-nil-or-a-table-got-s","errorCode":null,"errorMessage":"callback must return nil or a table, got %s","messagePattern":"callback must return nil or a table, got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/settings/lua/autocmd.go","lineNumber":619,"sourceCode":"\t\tif !isStr {\n\t\t\treturn \"\", false, fmt.Errorf(\"%s: callback must return a string or nil, got %s\", eventName, value.Type())\n\t\t}\n\n\t\trendered = string(str)\n\t\tok = true\n\t}\n\n\treturn rendered, ok, nil\n}\n\nfunc parseSearchFilterResult(value glua.LValue, valid map[SearchResultRef]int) ([]SearchResultRef, bool, error) {\n\tif value == glua.LNil {\n\t\treturn nil, false, nil\n\t}\n\n\ttbl, ok := value.(*glua.LTable)\n\tif !ok {\n\t\treturn nil, false, fmt.Errorf(\"callback must return nil or a table, got %s\", value.Type())\n\t}\n\n\tvar (\n\t\trefs     []SearchResultRef\n\t\tparseErr error\n\t)\n\n\tseen := mapset.NewThreadUnsafeSet[SearchResultRef]()\n\n\ttbl.ForEach(func(_ glua.LValue, val glua.LValue) {\n\t\tif parseErr != nil {\n\t\t\treturn\n\t\t}\n\n\t\tentry, ok := val.(*glua.LTable)\n\t\tif !ok {\n\t\t\tparseErr = fmt.Errorf(\"each result must be a table\")\n\t\t\treturn","sourceCodeStart":601,"sourceCodeEnd":637,"githubUrl":"https://github.com/Jguer/yay/blob/328f4b4939fb35f38c2f7c7ce3b8638a839bafa5/pkg/settings/lua/autocmd.go#L601-L637","documentation":"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.","triggerScenarios":"A search-filter autocmd callback returns a string, number, boolean, or function instead of nil or a table of result entries.","commonSituations":"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.","solutions":["Return nil to leave the result set unchanged.","Return a plain Lua table (array of {source=..., name=...} entries) — not a string or boolean.","Ensure the callback does not fall through returning the last expression's non-table value; add an explicit `return nil`."],"exampleFix":"-- before\nfilter = function(active) return true end\n-- after\nfilter = function(active) return nil end  -- or a table of result entries","handlingStrategy":"validation","validationCode":"-- Lua: guard the return value in the callback\nlocal out = compute_results()\nif out ~= nil and type(out) ~= \"table\" then out = nil end\nreturn out","typeGuard":null,"tryCatchPattern":"refs, _, err := engine.ApplySearchFilter(active)\nif err != nil {\n    log.Printf(\"filter returned wrong type (%v); ignoring filter\", err)\n    refs = nil\n}","preventionTips":["Return nil, not false or 0, to mean 'no filtering'","End the callback with an explicit `return nil` to avoid stray last-expression values","Only return plain Lua tables, never userdata or functions"],"tags":["lua","search-filter","callback","return-type"],"backgroundTag":"type-mismatch","analyzedSha":"328f4b4939fb35f38c2f7c7ce3b8638a839bafa5","analyzedAt":"2026-09-07T16:45:12.608Z","contentChangedAt":"2026-09-07T16:45:12.608Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}