这是indexloc提供的服务,不要输入任何密码
Skip to content

rego_compile_error when print()-ing value within nested comprehension #7647

@charlesdaniels

Description

@charlesdaniels

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
]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions