Jguer/yay · error
unsupported field kind
Error message
unsupported field kind %s
What it means
assign handles only string, bool, int/int64, and slice-of-struct fields; any other Go field kind (float, map, struct value, pointer, etc.) in a lua-tagged struct is unsupported and rejected with the field's reflect.Kind name. This is a schema constraint of the Lua settings engine, not a value problem in init.lua.
Solutions
- Change the unsupported field to a supported kind (string, bool, int, or []Struct)
- Store the value as an int where possible (e.g. seconds for durations)
- Remove the lua tag if the field should not be Lua-configurable
Example fix
// before Ratio float64 `lua:"ratio"` // after RatioPercent int `lua:"ratio_percent"`
Defensive patterns
Strategy: validation
Validate before calling
func checkLuaFieldKinds(t reflect.Type) error {
for i := 0; i < t.NumField(); i++ {
if t.Field(i).Tag.Get("lua") == "" { continue }
switch t.Field(i).Type.Kind() {
case reflect.String, reflect.Bool, reflect.Int, reflect.Int64, reflect.Slice:
default:
return fmt.Errorf("field %s has unsupported kind %s", t.Field(i).Name, t.Field(i).Type.Kind())
}
if t.Field(i).Type.Kind() == reflect.Slice && t.Field(i).Type.Elem().Kind() != reflect.Struct {
return fmt.Errorf("slice field %s must be []Struct", t.Field(i).Name)
}
}
return nil
} Try / catch
if err != nil && strings.Contains(err.Error(), "unsupported field kind") {
return fmt.Errorf("settings struct incompatible with lua engine: %w", err)
} Prevention
- Restrict lua-tagged fields to string, bool, int, or []Struct
- Add a reflect-based unit test that walks the settings struct and asserts supported kinds
- Avoid float64/time.Duration fields in Lua-configurable structs
When it happens
Trigger: Declaring a struct field with a lua tag whose kind is float64, map, nested struct, pointer, uint, etc., then running Load/Apply over it; a refactor changes a field's type away from the supported kinds.
Common situations: Adding a float option (Go defaults to float64) or a time.Duration field to the settings struct; embedding a sub-struct where a slice-of-struct was intended; using uint/int32.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- unsupported slice element kind
- lua: Apply expected pointer to struct, got %T
- SOCKS5 dialer does not support DialContext
AI-assisted analysis of Jguer/yay@328f4b4939 (2026-09-07).
Data as JSON: /api/errors/0181f03a9c752204.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/settings/lua/lua.go:184
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:
return assignStructSlice(field, val)
default:
return fmt.Errorf("unsupported field kind %s", field.Kind())
}
return nil
}
// assignStructSlice fills a []Struct field from a Lua table keyed by name, e.g.
//
// { ["core"] = { url = "..." }, ["extra"] = { url = "..." } }
//
// Each entry becomes one struct: the table key populates the element's
// lua:"name" field and the sub-table populates the remaining fields. Entries
// are sorted by name so the resulting slice is deterministic despite Lua's
// unordered table iteration.
func assignStructSlice(field reflect.Value, val lua.LValue) error {
elemType := field.Type().Elem()
if elemType.Kind() != reflect.Struct {
return fmt.Errorf("unsupported slice element kind %s", elemType.Kind())
}View on GitHub (pinned to 328f4b4939)