rego_type_error: match error
Just like the category suggests, this error is emitted by the type checker during the compilation stage. This error
is commonly triggered by comparing two values of different types, like a string and an integer ("1" == 1
). In order
for the error to be reported, the compiler must be able to determine the types involved in the expression.
This may sound obvious, but remember that some values and references aren't known until evaluation time. Comparing
something to e.g. a value from input
will therefore not be reported by the type checker (unless the type checker
has been informed
about the schema of input
).
Stage | Category | Message |
---|---|---|
compilation | rego_type_error | match error left: <type1> right: <type2> |
Examples
The first example is trivial, but serves well to demonstrate the error. An equality check between two literals of different type can never be true, and the compiler knows this:
package policy
import future.keywords.if
same if 1 == "1"
The error message reported will include the types compared in the match error:
1 error occurred: policy.rego:5: rego_type_error: match error
left : number
right : string
Some cases are more tricky however, and even comparison between two values of the same "simple" type can render a match error when composite types are on both sides of the comparison. Consider the following example:
package policy
import future.keywords.if
user1 := {"name": "joe", "age": 55}
user2 := {"name": "jane"}
same_user if user1 == user2
We're clearly comparing two objects, so should this really be a match error? The compiler would say yes:
1 error occurred: policy.rego:8: rego_type_error: match error
left : object<age: number, name: string>
right : object<name: string>
The reason for this is that while we may have objects on both sides, the type checker compares recursively. In doing
this it'll see that one object has an attribute (age
) that the other doesn't, and hence considered to be of
different type after all. This is sometimes considered
confusing, but given that it also allows catching some bugs at
compile time, it's likely the right behavior.
How To Fix It
Fixing this is simple: just change the types to match on both sides of a comparison. For the few cases where one really wants to compare two values of different types, a helper function can be used to "wash" off the type information from the comparison:
package policy
import future.keywords.if
user1 := {"name": "joe", "age": 55}
user2 := {"name": "jane"}
untyped_equals(o1, o2) if o1 == o2
# this will be undefined, not a compile time error
same_user if untyped_equals(user1, user2)
Do note — this is not a recommended approach! The type checker is there to help you, and circumventing it should be done only in exceptional cases.
Community
For questions, discussions and announcements related to OPA, or Styra products, services and open source projects, please join the Styra Community on Slack.