8000 bug: literal keyword bound in rule call resolves as entity UUID, silently mismatches keyword values in rule body · Issue #298 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

bug: literal keyword bound in rule call resolves as entity UUID, silently mismatches keyword values in rule body #298

Closed
project-minigraf/minigraf-playground
#43

Description

@adityamukho

Description

In v1.2.0, when a literal keyword is used to bind a rule argument at the call site, it is resolved to its entity UUID. If that bound variable is then used in a value position within the rule body, it silently fails to match stored Value::Keyword facts — returning empty results instead of the expected matches.

Reproduction

(transact [[:bob :employee/manager :alice]])
(transact [[:carol :employee/manager :alice]])

(rule [(reports-to ?emp ?mgr) [?emp :employee/manager ?mgr]])

; Direct query — works correctly:
(query [:find ?emp :where [?emp :employee/manager :alice]])
; → returns bob and carol

; Rule with literal in body — works:
(rule [(manages ?emp) [?emp :employee/manager :alice]])
(query [:find ?emp :where (manages ?emp)])
; → returns bob and carol

; Rule with variable bound at call site — silently returns empty:
(query [:find ?emp :where (reports-to ?emp :alice)])
; → {"results":[],"variables":["?emp"]}  ← BUG: should return bob and carol

Root cause hypothesis

When :alice is used in the rule call (reports-to ?emp :alice), it appears to be resolved as an entity UUID (as if it were in entity position). The rule body [?emp :employee/manager ?mgr] then tries to match against stored facts where :employee/manager values are Value::Keyword(":alice"). The UUID doesn't match the keyword — hence empty results.

Direct queries handle this correctly; the bug is specific to bound variable propagation from rule call sites into rule body value-position patterns.

Contrast with entity-position binding (works)

(transact [[:a :edge :b][:b :edge :c]])
(rule [(reach ?x ?y) [?x :edge ?y]])

; Binding ?x (entity position) via literal — works:
(query [:find ?y :where (reach :a ?y)])
; → returns :b and :c

Entity-position binding works because entity values are stored as UUIDs consistently.

Affected versions

Introduced in v1.2.0. v1.1.1 is not affected.

Workaround

Look up the target entity via a fact pattern to get the UUID, then pass it into the rule:

[?alice :employee/title "CEO"]
(reports-to ?emp ?alice)

Relation to #297

Both bugs are triggered by literal keyword binding in rule calls, but manifest differently:

Activity

  1. added this to the v1.2.1 milestone on Jun 28, 2026
  2. added a commit that references this issue on Jun 28, 2026
  3. added a commit that references this issue on Jun 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0