There are two primary causes of this error: trying to add a two-sided constraint, and using NumPy scalars on the left-hand side of a constraint.
Adding a two-sided constraint
Starting from Gurobi Optimizer 9.0.0, you may see this error when trying to add two-sided constraints like 1 <= x <= 2 through the Python API. Adding two-sided constraints is not supported in Gurobi 9.0 and later. Although the same syntax did not result in an error in Gurobi 8.1.1 and earlier, adding two-sided constraints was not supported and the behavior was not as expected. This is noted in the Gurobi 8.1.1 documentation here:
"Note that double inequality constraints, like 1 <= x + y <= 2 or 1 <= x[i] + y[i] <= 2 for i in range(3) are NOT supported in this API, and will result in one of the inequalities to be silently disregarded, which will result in unexpected behavior."
For example, consider the following code:
m = Model()
x = m.addVar(name="x")
m.addConstr(1 <= x <= 2, name="twosided")
In Gurobi 8.1.1, this results in the following model (in LP format):
twosided: x <= 2
Note that the constraint 1 <= x is missing. With v9.0.0 and later, Gurobi actively prohibits this syntax by throwing an error, preventing unexpected behavior like this. Instead, each of the two constraints can be added to the model separately:
m.addConstr(1 <= x, name="lefthandside")
m.addConstr(x <= 2, name="righthandside")
Using NumPy scalars on left-hand side of constraint
This error can also occur when using NumPy scalars (such as numpy.int32, numpy.int64, numpy.float32, or numpy.float64) on the left-hand side of a constraint. For example, the following code results in the "Constraint has no bool value" error:
import numpy as np
import gurobipy as gp
model = gp.Model()
x = model.addVar()
a = np.float64(5)
model.addConstr(a >= x) # error!
The error is a result of Python using the __ge__ (or __le__) method from the appropriate NumPy data class, which is not meant for constructing Gurobi constraint expressions.
Two possible workarounds are:
- Recast the NumPy data structure into a standard Python numeric type like int or float. In this case, the last line becomes model.addConstr(int(a) >= x).
- Rewrite the constraint so the left-hand side expression begins with a Var or LinExpr object. With this workaround, the last line becomes instead model.addConstr(x <= a).