Jguer/yay · error
keys must be strings, got
Error message
keys must be strings, got %s
What it means
Thrown by `assignStructFields` when a key inside a struct-mapped Lua table is not a Lua string. Struct fields are looked up by string key against `lua:"..."` tags, so numeric or other key types cannot be matched.
Solutions
- Replace numeric keys in the option table with the documented string field names.
- Check the Go struct's lua tags for the exact key names.
- If the option truly needs a list, it should be a slice-type option, not a struct option.
Example fix
-- before
aur = { [1] = true }
-- after
aur = { build = true } Defensive patterns
Strategy: validation
Validate before calling
-- ensure all keys in the entry table are strings for k, _ in pairs(entry) do assert(type(k) == "string", "keys must be strings, got " .. type(k)) end
Prevention
- Never mix array syntax `[1]=...` into struct-style option tables
- Avoid computed/integer keys in config tables
- Use `pairs` iteration in any config-generating Lua code and assert string keys
When it happens
Trigger: An entry table written as an array (`{ [1] = ..., [2] = ... }`) or with computed/integer keys inside a named-entry option; `k.(lua.LString)` assertion fails during `tbl.ForEach`.
Common situations: Users mixing list syntax with table syntax, e.g. `build = { "make", "install" }` where the option expects named fields, or Lua code building keys with integers.
Related errors
AI-assisted analysis of Jguer/yay@328f4b4939 (2026-09-07).
Data as JSON: /api/errors/638e8b2fbd9e28cf.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/settings/lua/lua.go:289
field.Set(out)
return nil
}
// assignStructFields assigns the entries of tbl onto struct value sv, matching
// each key against the lua:"..." tags in index. Unknown keys are errors so
// typos in nested option tables fail fast, mirroring top-level opt handling.
func assignStructFields(sv reflect.Value, tbl *lua.LTable, index map[string]int) error {
var firstErr error
tbl.ForEach(func(k, entry lua.LValue) {
if firstErr != nil {
return
}
key, ok := k.(lua.LString)
if !ok {
firstErr = fmt.Errorf("keys must be strings, got %s", k.Type())
return
}
fieldIdx, found := index[string(key)]
if !found {
firstErr = fmt.Errorf("unknown key %q", string(key))
return
}
if err := assign(sv.Field(fieldIdx), entry); err != nil {
firstErr = fmt.Errorf("%s: %w", string(key), err)
}
})
return firstErr
}
View on GitHub (pinned to 328f4b4939)