Jguer/yay · error

entry

Error message

entry %q: %w

What it means

A wrapper error: after an entry table passes the type check, `assignStructFields` populates the Go struct from the entry's keys, and any failure there is re-wrapped as `entry "<name>": <cause>` so the offending entry name is preserved in the chain.

Solutions

  1. Read the wrapped cause after `entry %q:` to find the exact key that failed.
  2. Fix the named entry table in the Lua config so all keys match the documented struct fields.
  3. Validate one entry at a time by temporarily reducing the option table to a single entry.

Example fix

-- before (typo)
debug = { lbel = true }
-- after
debug = { label = true }
Defensive patterns

Strategy: try-catch

Validate before calling

-- pre-check keys of one entry against allowed fields
local allowed = { field = true, other = true }
for k in pairs(entry) do assert(allowed[k], "unknown key " .. k) end

Try / catch

if err := loader.Load(cfg); err != nil {
    var entryErr *fmt.WrapError // unwrap chain
    // log err: message contains `entry "<name>": <cause>`
    return fmt.Errorf("config invalid: %w", err)
}

Prevention

When it happens

Trigger: Any inner failure while decoding one named entry: non-string key inside the entry table, an unknown key not matching a `lua:"..."` struct tag, or a value whose type doesn't match the target struct field.

Common situations: Typos in field names inside a nested Lua option table, using numeric/array keys where named keys are required, or wrong value types (e.g. string where number expected) inside one entry of a multi-entry option.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Jguer/yay@328f4b4939 (2026-09-07). Data as JSON: /api/errors/452b5d60fbbf85b0. Report an issue: GitHub.

Appendix: source

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

		name, ok := k.(lua.LString)
		if !ok {
			firstErr = fmt.Errorf("entry keys must be strings, got %s", k.Type())
			return
		}

		entryTbl, ok := entry.(*lua.LTable)
		if !ok {
			firstErr = fmt.Errorf("entry %q must be a table, got %s", string(name), entry.Type())
			return
		}

		elem := reflect.New(elemType).Elem()
		if hasName {
			elem.Field(nameIdx).SetString(string(name))
		}

		if err := assignStructFields(elem, entryTbl, fieldIndex); err != nil {
			firstErr = fmt.Errorf("entry %q: %w", string(name), err)
			return
		}

		entries = append(entries, namedElem{name: string(name), elem: elem})
	})

	if firstErr != nil {
		return firstErr
	}

	// Sort by name so the resulting slice is deterministic despite Lua's
	// unordered table iteration.
	slices.SortFunc(entries, func(a, b namedElem) int {
		return strings.Compare(a.name, b.name)
	})

	out := reflect.MakeSlice(field.Type(), len(entries), len(entries))
	for i, entry := range entries {

View on GitHub (pinned to 328f4b4939)