Jguer/yay · error

expected string, got

Error message

expected string, got %s

What it means

assign maps a Lua value onto a reflect.String struct field and requires the raw Lua value to be an LString. Any other Lua type (number, boolean, nil, table) cannot be stored in the string field, so it reports the offending Lua type name via val.Type().

Solutions

  1. Wrap the value in quotes in init.lua: yay.opt.editor = "nvim"
  2. Convert non-string Lua values with tostring(...) only if the numeric/boolean text is truly intended as a string
  3. Verify the struct field is actually a string kind; if it should be bool/number, fix the Go struct tag instead

Example fix

// before (init.lua)
yay.opt.editor = nvim
// after
yay.opt.editor = "nvim"
Defensive patterns

Strategy: validation

Validate before calling

-- init.lua
assert(type(yay.opt.editor) == "string", "yay.opt.editor must be a string")

Try / catch

if err != nil && strings.Contains(err.Error(), "expected string") {
    fixStringOptionInInitLua()
}

Prevention

When it happens

Trigger: An init.lua option bound to a Go string field is set to a non-string, e.g. yay.opt.editor = true or yay.opt.editor = 5 or a table.

Common situations: Quoting habits from other languages reversed — forgetting quotes when a string looks like a number elsewhere; assigning nil to 'clear' a string; an editor path accidentally written as a boolean expression result.

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/862ff7cd7dd126e9. Report an issue: GitHub.

Appendix: source

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

func luaFieldIndex(st reflect.Type) map[string]int {
	index := make(map[string]int, st.NumField())

	for i := range st.NumField() {
		field := st.Field(i)
		if name := luaKeyForField(&field); name != "" {
			index[name] = i
		}
	}

	return index
}

func assign(field reflect.Value, val lua.LValue) error {
	switch field.Kind() {
	case reflect.String:
		s, ok := val.(lua.LString)
		if !ok {
			return fmt.Errorf("expected string, got %s", val.Type())
		}

		field.SetString(string(s))
	case reflect.Bool:
		b, ok := val.(lua.LBool)
		if !ok {
			return fmt.Errorf("expected boolean, got %s", val.Type())
		}

		field.SetBool(bool(b))
	case reflect.Int, reflect.Int64:
		n, ok := val.(lua.LNumber)
		if !ok {
			return fmt.Errorf("expected number, got %s", val.Type())
		}

		field.SetInt(int64(n))
	case reflect.Slice:

View on GitHub (pinned to 328f4b4939)