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

  1. Change the unsupported field to a supported kind (string, bool, int, or []Struct)
  2. Store the value as an int where possible (e.g. seconds for durations)
  3. 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

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


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)