Skip to content

checker: recognize table<...>/bare table as a table-shaped alternative - #22

Merged
Paritsingla7 merged 1 commit into
mainfrom
fix/table-type-alternative-false-positive
Aug 29, 2026
Merged

Paritsingla7 merged 1 commit into
mainfrom
fix/table-type-alternative-false-positive

Conversation

@Paritsingla7

Copy link
Copy Markdown
Owner

Summary

Found by actually running hyprvalidate check against two independent, real-world, distribution/project-scale Hyprland Lua configs — not synthetic testing.

Both are real, public, unauthenticated-fetchable repos — verified directly, not taken on faith.

The bug (hyprvalidate's own)

_has_table_alternative only checked for { or HL. in a type expression to decide "is this a table shape, not a scalar." It missed LuaLS's generic table<K, V> syntax and the bare table alternative entirely. HL.LayerRuleSpec.match is typed table<string, string|boolean> — so every real layer rule with a match table was a false positive, in both configs identically, since a match table is the only way to write a layer rule at all (7 false positives in Garuda's config, 4 in sea-shell's).

Fix: _has_table_alternative now also checks for "table" in the type expression. Verified: both real configs' layer-rule findings disappear completely; existing tests (including the HL.Gradient table-alternative case) still pass.

A second finding — upstream, not ours to fix

Both configs also use hl.bind(..., { mouse = true }), flagged as 'mouse' is not a field of HL.BindOptions. Traced directly into Hyprland's own source: mouse is a real, implemented flag (LuaKeybind.cpp, parsed identically to click/drag, which are in the schema) — it's just missing, along with auto_consuming, device_inclusive, and devices, from a hand-written field list in Hyprland's own meta/generateLuaStubs.py (lines ~658–677). That's the exact "hand-maintained table drifts from what's real" bug class this project exists to catch — just found one level further upstream. Not fixable here without hand-maintaining the same kind of table this project refuses to elsewhere. Noted in the CHANGELOG as a candidate for an upstream report — not filed yet, pending a decision on whether/how to do that.

Test plan

  • pytest tests/ — 205 passed (3 pre-existing/environmental entry-point failures unrelated, deselected)
  • Re-ran both real configs after the fix: the 11 layer-rule false positives are gone; only the genuine upstream mouse gap remains (2 findings, unchanged, correctly not something hyprvalidate can resolve)
  • site/bundle.js regenerated (checker.py changed)

_has_table_alternative only checked for "{" or "HL." in a type
expression - missing LuaLS's generic table<K, V> syntax and the bare
"table" alternative entirely (e.g. HL.LayerRuleSpec.match: table<string,
string|boolean>, or config keys typed integer|table). Every real layer
rule with a match table was a false positive.

Found by running check against two independent real-world Hyprland Lua
configs - Garuda Linux's distribution-shipped settings
(garuda-hyprland-settings) and the sea-shell project - both of which
hit this identically, since a match table is the only way to write a
layer rule at all.

The same run surfaced a second, genuinely upstream gap, not a
hyprvalidate bug: both configs also use hl.bind(..., { mouse = true }),
and `mouse` isn't in HL.BindOptions. Traced into Hyprland's own source:
mouse is a real, implemented flag (LuaKeybind.cpp, parsed identically
to click/drag, which ARE in the schema) missing - along with
auto_consuming, device_inclusive, and devices - from a hand-written
field list in Hyprland's own meta/generateLuaStubs.py. Not fixable
here without hand-maintaining the same kind of table this project
exists to avoid; noted in CHANGELOG as an upstream-report candidate.
@Paritsingla7
Paritsingla7 merged commit f2f325f into main Aug 29, 2026
6 checks passed
@Paritsingla7 Paritsingla7 mentioned this pull request Aug 29, 2026
2 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant