Jguer/yay · error

unknown key

Error message

unknown key %q

What it means

Thrown when a key in a struct-mapped Lua entry table does not match any `lua:"..."` struct tag in the target Go struct. The loader intentionally fails fast on unknown keys so typos in nested option tables are reported instead of silently ignored.

Solutions

  1. Correct the key to the name reported in the `unknown key` message by checking the struct's lua tags or documentation.
  2. Remove the key if it is no longer supported after a version upgrade.
  3. Run the config through the loader after each upgrade to catch renamed fields early.

Example fix

-- before (renamed option)
devel = { dbug = true }
-- after
devel = { debug = true }
Defensive patterns

Strategy: validation

Validate before calling

-- lint config keys against the documented schema
local schema = { debug = true, verbose = true }
for k, _ in pairs(entry) do
  if not schema[k] then error("unknown key " .. tostring(k)) end
end

Prevention

When it happens

Trigger: A Lua config containing a misspelled or obsolete field inside an entry, e.g. `entry = { fiels = 1 }` where the struct defines `field`; `index[string(key)]` lookup misses.

Common situations: Upstream renames an option field and the user's config still uses the old name; copy-pasted config from a different tool; simple typos.

Related errors


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

Appendix: source

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

// each key against the lua:"..." tags in index. Unknown keys are errors so
// typos in nested option tables fail fast, mirroring top-level opt handling.
func assignStructFields(sv reflect.Value, tbl *lua.LTable, index map[string]int) error {
	var firstErr error

	tbl.ForEach(func(k, entry lua.LValue) {
		if firstErr != nil {
			return
		}

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

		fieldIdx, found := index[string(key)]
		if !found {
			firstErr = fmt.Errorf("unknown key %q", string(key))
			return
		}

		if err := assign(sv.Field(fieldIdx), entry); err != nil {
			firstErr = fmt.Errorf("%s: %w", string(key), err)
		}
	})

	return firstErr
}

View on GitHub (pinned to 328f4b4939)