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
- Wrap the value in quotes in init.lua: yay.opt.editor = "nvim"
- Convert non-string Lua values with tostring(...) only if the numeric/boolean text is truly intended as a string
- 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
- Quote all string options in init.lua
- Never assign nil to string options; use empty string ""
- Check the Go struct field kind before adding a new yay.opt key
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)