-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Short description
I have found that when attempting to print a value that is dependent on an inner comprehension from within the right hand side of an outer comprehension, Rego incorrectly throws a rego_compile_error
. I initially found this while working with rq.tree()
for some data science, but have confirmed it reproduces in vanilla OPA as well.
Steps To Reproduce
This Rego command runs just fine:
$ printf '%s' '{"a":[1,2,3],"b":[4,5,6],"c":[7,8,9]}' | opa eval -f pretty -I '{v | m := {l | l := input[k]}[_]; v := m[_]}'
[
1,
2,
3,
4,
5,
6,
7,
8,
9
]
However, attempting to print v
causes a compile error:
$ printf '%s' '{"a":[1,2,3],"b":[4,5,6],"c":[7,8,9]}' | opa eval -f pretty -I '{v | m := {l | l := input[k]}[_]; v := m[_]; print(v)}'
1 error occurred: 1:52: rego_compile_error: var __localq2__ is undeclared
Expected behavior
I expected the second command to produce the same JSON output as the first, and additionally to print the values 1, 2, 3..., 8, 9
to stderr from the print()
command as well.
Additional context
$ opa version
Version: 1.5.0
Build Commit: b7d0a13145cdda058435fed90b10f7c22b4b99b1
Build Timestamp: 2025-05-29T14:21:03Z
Build Hostname:
Go Version: go1.24.3
Platform: darwin/arm64
Rego Version: v1
WebAssembly: unavailable
This behavior also impacts rq 0.0.14, which embeds OPA 1.3.0, so it's likely this issue at least goes back to 1.3.0 and possibly earlier versions.
List comprehensions are impacted as well as set comprehensions:
$ printf '%s' '{"a":[1,2,3],"b":[4,5,6],"c":[7,8,9]}' | opa eval -f pretty -I '[v | m := {l | l := input[k]}[_]; v := m[_]]'
[
1,
2,
3,
4,
5,
6,
7,
8,
9
]
$ printf '%s' '{"a":[1,2,3],"b":[4,5,6],"c":[7,8,9]}' | opa eval -f pretty -I '[v | m := {l | l := input[k]}[_]; v := m[_]; print(v)]'
1 error occurred: 1:52: rego_compile_error: var __localq2__ is undeclared
Smuggling the input through a builtin to make it runtime dynamic does not have any impact. I initially thought that this was actually required, but I later figured out just using input
normally with no tricks triggered this behavior too.
$ printf '%s' '"{\"a\":[1,2,3],\"b\":[4,5,6],\"c\":[7,8,9]}"' | opa eval -f pretty -I '[v | m := [l | l := json.unmarshal(input)[k]][_]; v := m[_]; print(v)]'
1 error occurred: 1:68: rego_compile_error: var __localq2__ is undeclared
$ printf '%s' '"{\"a\":[1,2,3],\"b\":[4,5,6],\"c\":[7,8,9]}"' | opa eval -f pretty -I '[v | m := [l | l := json.unmarshal(input)[k]][_]; v := m[_]]'
[
1,
2,
3,
4,
5,
6,
7,
8,
9
]
Non-nested comprehensions are not impacted:
$ printf '%s' '"{\"a\":[1,2,3],\"b\":[4,5,6],\"c\":[7,8,9]}"' | opa eval -f pretty -I '{v | l := json.unmarshal(input)[k]; v := l[_]; print(v)}'
1
2
3
4
5
6
7
8
9
[
1,
2,
3,
4,
5,
6,
7,
8,
9
]
$ printf '%s' '"{\"a\":[1,2,3],\"b\":[4,5,6],\"c\":[7,8,9]}"' | opa eval -f pretty -I '{v | l := json.unmarshal(input)[k]; v := l[_]; print(l)}'
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
[4, 5, 6]
[4, 5, 6]
[4, 5, 6]
[7, 8, 9]
[7, 8, 9]
[7, 8, 9]
[
1,
2,
3,
4,
5,
6,
7,
8,
9
]