Jguer/yay · error

lua: Apply expected pointer to struct, got %T

Error message

lua: Apply expected pointer to struct, got %T

What it means

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.

Solutions

  1. Pass a pointer to your settings struct: engine.Apply(&cfg)
  2. Check the type in the error message (%T) and make sure the pointed-to kind is struct
  3. If your settings live in a map, refactor into a struct with lua-tagged fields

Example fix

// before
var cfg Settings
engine.Apply(cfg)
// after
var cfg Settings
engine.Apply(&cfg)
Defensive patterns

Strategy: type-guard

Validate before calling

func validateApplyTarget(cfg any) error {
    v := reflect.ValueOf(cfg)
    if v.Kind() != reflect.Pointer || v.Elem().Kind() != reflect.Struct {
        return fmt.Errorf("Apply needs *Struct, got %T", cfg)
    }
    return nil
}

Type guard

func isStructPtr(cfg any) bool {
    v := reflect.ValueOf(cfg)
    return v.Kind() == reflect.Pointer && v.Elem().Kind() == reflect.Struct
}
if !isStructPtr(cfg) { return errors.New("cfg must be a pointer to struct") }
engine.Apply(cfg)

Try / catch

if _, err := engine.Apply(&cfg); err != nil {
    return fmt.Errorf("applying lua settings: %w", err)
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at pkg/settings/lua/lua.go:61

	state.SetField(yayTbl, "create_autocmd", state.NewFunction(engine.createAutocmd))
	engine.registerLog(yayTbl)

	return engine
}

func (e *Engine) SetLogger(logger *text.Logger) {
	e.logger = logger
}

func (e *Engine) Close() {
	e.L.Close()
}

// Apply writes recognized yay.opt values into cfg.
func (e *Engine) Apply(cfg any) (unknown []string, errs []error) {
	v := reflect.ValueOf(cfg)
	if v.Kind() != reflect.Pointer || v.Elem().Kind() != reflect.Struct {
		return nil, []error{fmt.Errorf("lua: Apply expected pointer to struct, got %T", cfg)}
	}

	sv := v.Elem()
	index := luaFieldIndex(sv.Type())

	optTbl, ok := e.optTable()
	if !ok {
		return nil, nil
	}

	optTbl.ForEach(func(k, val lua.LValue) {
		key, ok := k.(lua.LString)
		if !ok {
			return
		}

		fieldIdx, found := index[string(key)]
		if !found {

View on GitHub (pinned to 328f4b4939)