Jguer/yay · error

unsupported slice element kind

Error message

unsupported slice element kind %s

What it means

assignStructSlice implements the Slice case of assign but only supports slices whose element type is a struct ([]Struct with a lua:"name" field). Any other element kind ([]string, []int, []any) is rejected, naming the element's reflect.Kind.

Solutions

  1. Change the field to a slice of a named struct with a lua:"name" key field (e.g. []Pkg where Pkg has Name string `lua:"name"`)
  2. Model key–value string lists as that struct slice, one entry per name
  3. Remove the lua tag from the field if it should not be Lua-configurable

Example fix

// before
Ignored []string `lua:"ignored"`
// after
type IgnoredPkg struct{ Name string `lua:"name"` }
Ignored []IgnoredPkg `lua:"ignored"`
Defensive patterns

Strategy: validation

Validate before calling

func isStructSlice(f any) bool {
    t := reflect.TypeOf(f)
    if t == nil || t.Kind() != reflect.Slice { return false }
    return t.Elem().Kind() == reflect.Struct
}

Type guard

func sliceOfStruct(f reflect.StructField) bool {
    return f.Type.Kind() == reflect.Slice && f.Type.Elem().Kind() == reflect.Struct
}

Try / catch

if err != nil && strings.Contains(err.Error(), "unsupported slice element kind") {
    return fmt.Errorf("lua settings require []Struct fields: %w", err)
}

Prevention

When it happens

Trigger: A lua-tagged struct field is declared as []string, []int, or another non-struct slice, and init.lua assigns a table to the corresponding yay.opt key; or a refactor changes the element type of an existing slice field.

Common situations: Wanting a list of strings (e.g. yay.opt.ignored_pkgs = {"a","b"}) and modeling it as []string, which the engine does not support.

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/9b11c3585b183cd3. Report an issue: GitHub.

Appendix: source

Thrown at pkg/settings/lua/lua.go:201

	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())
	}

	tbl, ok := val.(*lua.LTable)
	if !ok {
		return fmt.Errorf("expected table, got %s", val.Type())
	}

	// The name comes from the table key, so a "name" key inside the entry table
	// would silently override it and let two entries share one name. Drop it
	// from the assignable set so it is reported as an unknown key instead.
	fieldIndex := luaFieldIndex(elemType)
	nameIdx, hasName := fieldIndex["name"]
	delete(fieldIndex, "name")

	type namedElem struct {
		name string
		elem reflect.Value
	}

View on GitHub (pinned to 328f4b4939)