{"record":{"id":"1ae562eaba8ca94e","repo":"Jguer/yay","slug":"lua-apply-expected-pointer-to-struct-got-t","errorCode":null,"errorMessage":"lua: Apply expected pointer to struct, got %T","messagePattern":"lua: Apply expected pointer to struct, got %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/settings/lua/lua.go","lineNumber":61,"sourceCode":"\tstate.SetField(yayTbl, \"create_autocmd\", state.NewFunction(engine.createAutocmd))\n\tengine.registerLog(yayTbl)\n\n\treturn engine\n}\n\nfunc (e *Engine) SetLogger(logger *text.Logger) {\n\te.logger = logger\n}\n\nfunc (e *Engine) Close() {\n\te.L.Close()\n}\n\n// Apply writes recognized yay.opt values into cfg.\nfunc (e *Engine) Apply(cfg any) (unknown []string, errs []error) {\n\tv := reflect.ValueOf(cfg)\n\tif v.Kind() != reflect.Pointer || v.Elem().Kind() != reflect.Struct {\n\t\treturn nil, []error{fmt.Errorf(\"lua: Apply expected pointer to struct, got %T\", cfg)}\n\t}\n\n\tsv := v.Elem()\n\tindex := luaFieldIndex(sv.Type())\n\n\toptTbl, ok := e.optTable()\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\n\toptTbl.ForEach(func(k, val lua.LValue) {\n\t\tkey, ok := k.(lua.LString)\n\t\tif !ok {\n\t\t\treturn\n\t\t}\n\n\t\tfieldIdx, found := index[string(key)]\n\t\tif !found {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/Jguer/yay/blob/328f4b4939fb35f38c2f7c7ce3b8638a839bafa5/pkg/settings/lua/lua.go#L43-L79","documentation":"Engine.Apply only knows how to write Lua settings into a pointer to a Go struct; any other shape cannot be reflected into. It rejects the argument up front with a message showing the actual Go type received, before touching any settings.","triggerScenarios":"Calling engine.Apply(cfg) where cfg is not a pointer, or is a pointer to a non-struct (e.g. *map[string]any, *int, or a plain struct value rather than &struct).","commonSituations":"Passing a struct by value instead of its address; decoding into a map and passing the map; passing nil or an interface holding a non-pointer.","solutions":["Pass a pointer to your settings struct: engine.Apply(&cfg)","Check the type in the error message (%T) and make sure the pointed-to kind is struct","If your settings live in a map, refactor into a struct with lua-tagged fields"],"exampleFix":"// before\nvar cfg Settings\nengine.Apply(cfg)\n// after\nvar cfg Settings\nengine.Apply(&cfg)","handlingStrategy":"type-guard","validationCode":"func validateApplyTarget(cfg any) error {\n    v := reflect.ValueOf(cfg)\n    if v.Kind() != reflect.Pointer || v.Elem().Kind() != reflect.Struct {\n        return fmt.Errorf(\"Apply needs *Struct, got %T\", cfg)\n    }\n    return nil\n}","typeGuard":"func isStructPtr(cfg any) bool {\n    v := reflect.ValueOf(cfg)\n    return v.Kind() == reflect.Pointer && v.Elem().Kind() == reflect.Struct\n}\nif !isStructPtr(cfg) { return errors.New(\"cfg must be a pointer to struct\") }\nengine.Apply(cfg)","tryCatchPattern":"if _, err := engine.Apply(&cfg); err != nil {\n    return fmt.Errorf(\"applying lua settings: %w\", err)\n}","preventionTips":["Always pass &cfg, never cfg","Keep settings in a struct, not a map","Add a unit test asserting Apply accepts your settings type"],"tags":["go","reflection","type-mismatch"],"backgroundTag":"invalid-argument-value","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"}