{"record":{"id":"638e8b2fbd9e28cf","repo":"Jguer/yay","slug":"keys-must-be-strings-got-s","errorCode":null,"errorMessage":"keys must be strings, got %s","messagePattern":"keys must be strings, got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/settings/lua/lua.go","lineNumber":289,"sourceCode":"\tfield.Set(out)\n\n\treturn nil\n}\n\n// assignStructFields assigns the entries of tbl onto struct value sv, matching\n// each key against the lua:\"...\" tags in index. Unknown keys are errors so\n// typos in nested option tables fail fast, mirroring top-level opt handling.\nfunc assignStructFields(sv reflect.Value, tbl *lua.LTable, index map[string]int) error {\n\tvar firstErr error\n\n\ttbl.ForEach(func(k, entry lua.LValue) {\n\t\tif firstErr != nil {\n\t\t\treturn\n\t\t}\n\n\t\tkey, ok := k.(lua.LString)\n\t\tif !ok {\n\t\t\tfirstErr = fmt.Errorf(\"keys must be strings, got %s\", k.Type())\n\t\t\treturn\n\t\t}\n\n\t\tfieldIdx, found := index[string(key)]\n\t\tif !found {\n\t\t\tfirstErr = fmt.Errorf(\"unknown key %q\", string(key))\n\t\t\treturn\n\t\t}\n\n\t\tif err := assign(sv.Field(fieldIdx), entry); err != nil {\n\t\t\tfirstErr = fmt.Errorf(\"%s: %w\", string(key), err)\n\t\t}\n\t})\n\n\treturn firstErr\n}\n","sourceCodeStart":271,"sourceCodeEnd":306,"githubUrl":"https://github.com/Jguer/yay/blob/328f4b4939fb35f38c2f7c7ce3b8638a839bafa5/pkg/settings/lua/lua.go#L271-L306","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","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."],"exampleFix":"-- before\naur = { [1] = true }\n-- after\naur = { build = true }","handlingStrategy":"validation","validationCode":"-- ensure all keys in the entry table are strings\nfor k, _ in pairs(entry) do\n  assert(type(k) == \"string\", \"keys must be strings, got \" .. type(k))\nend","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["lua","config","type-error","keys"],"backgroundTag":"config-type-mismatch","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"}