Skip to main content

rego_type_error: conflicting rules {name} found

This error happens when a rule is incrementally defined in a way that contradicts itself. This could for example happen when a rule is declared to be both single-value and multi-value, or when a function is declared twice with a different number of arguments (i.e. different arity).

StageCategoryMessage
compilationrego_type_errorconflicting rules {name} found (where name is the reference to a rule or function)

Examples

In the following example, the deny rule is first declared to be a boolean single-value rule, and then later declared to be a multi-value rule building a set of strings. Since a rule can't reasonably both evaluate to a boolean and a set, this will cause a conflict:

package policy

import future.keywords.contains
import future.keywords.if
import future.keywords.in

deny if {
input.request.method == "PUT"
not "admin" in input.user.roles
}

deny contains reason if {
input.request.method == "PUT"
not "admin" in input.user.roles

reason := "only admins can modify resources"
}
1 error occurred: policy.rego:7: rego_type_error: conflicting rules data.policy.deny found

Another example would be a function that is declared twice with different, conflicting, arity:

package policy

import future.keywords.if
import future.keywords.in

find(arr, item) := item if item in arr

find(arr, item, not_found) := not_found if not item in arr

While overloading functions on arity might work in some languages, it is not supported in Rego.

1 error occurred: policy.rego:6: rego_type_error: conflicting rules data.policy.find found

How To Fix It

Use a composite type, like objects, to return multiple values — like a boolean and a set of strings — from a rule. In the example below, we've added a decision rule, which compiles its value from both the boolean deny rule and the reasons set-generating rule:

package policy

import future.keywords.contains
import future.keywords.if
import future.keywords.in

decision["deny"] := deny
decision["reasons"] := reasons if deny

default deny := false

deny if {
input.request.method == "PUT"
not "admin" in input.user.roles
}

reasons contains reason if {
input.request.method == "PUT"
not "admin" in input.user.roles

reason := "only admins can modify resources"
}

For the case of functions, simply ensure that the same arity is used for all declarations of the function. Use the wildcard operator (_) for arguments that are unused in any given declaration:

package policy

import future.keywords.if
import future.keywords.in

find(arr, item, _) := item if item in arr

find(arr, item, not_found) := not_found if not item in arr

Community

For questions, discussions and announcements related to OPA, or Styra products, services and open source projects, please join the Styra Community on Slack.