You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
using JuMP
import MathOptInterface as MOI
import ParametricOptInterface as POI
using Clarabel
opt = POI.Optimizer(
MOI.instantiate(Clarabel.Optimizer; with_bridge_type = Float64, with_cache_type = Float64),
)
m =direct_model(opt)
set_silent(m)
@variable(m, x >=0) # key trigger@variable(m, p in MOI.Parameter(1.0))
@constraint(m, x == p)
@objective(m, Min, x)
optimize!(m) # worksset_parameter_value(p, 2.0)
optimize!(m) # throws SetAttributeNotAllowed{ConstraintSet}
The error:
ERROR: MathOptInterface.SetAttributeNotAllowed{MathOptInterface.ConstraintSet}:
## Cause
Setting attribute MathOptInterface.ConstraintSet() cannot be performed
## Fixing this error
An `MOI.NotAllowedError` error occurs when you have tried to do something that
is not implemented by the solver.
The most common way to fix this error is to wrap the optimizer in a
`MOI.Utilities.CachingOptimizer`.
For example, if you are using `JuMP.Model` or `JuMP.set_optimizer`, do:
``julia
model = JuMP.Model(optimizer; with_cache_type = Float64)
model = JuMP.GenericModel{T}(optimizer; with_cache_type = T)
JuMP.set_optimizer(model, optimizer; with_cache_type = Float64)
``
Similarly, if you are using `MOI.instantiate`, do:
``julia
model = MOI.instantiate(optimizer; with_cache_type = Float64)
``
Stacktrace:
[1] set(b::MathOptInterface.Bridges.LazyBridgeOptimizer{…}, attr::MathOptInterface.ConstraintSet, ci::MathOptInterface.ConstraintIndex{…}, set::MathOptInterface.EqualTo{…})
@ MathOptInterface.Bridges /tmp/ar_julia_depot/packages/MathOptInterface/Q3V1z/src/Bridges/bridge_optimizer.jl:1585
[2] _update_affine_constraints!(model::ParametricOptInterface.Optimizer{…}, affine_constraint_cache_inner::MathOptInterface.Utilities.DoubleDicts.DoubleDictInner{…}, affine_constraint_cache_set_inner::MathOptInterface.Utilities.DoubleDicts.DoubleDictInner{…})
@ ParametricOptInterface /tmp/ar_julia_depot/packages/ParametricOptInterface/qeWEl/src/update_parameters.jl:63
[3] _update_affine_constraints!(model::ParametricOptInterface.Optimizer{…})
@ ParametricOptInterface /tmp/ar_julia_depot/packages/ParametricOptInterface/qeWEl/src/update_parameters.jl:32
[4] update_parameters!(model::ParametricOptInterface.Optimizer{Float64, MathOptInterface.Bridges.LazyBridgeOptimizer{…}})
@ ParametricOptInterface /tmp/ar_julia_depot/packages/ParametricOptInterface/qeWEl/src/update_parameters.jl:293
[5] optimize!(model::ParametricOptInterface.Optimizer{Float64, MathOptInterface.Bridges.LazyBridgeOptimizer{…}})
@ ParametricOptInterface /tmp/ar_julia_depot/packages/ParametricOptInterface/qeWEl/src/MOI_wrapper.jl:2068
[6] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::@Kwargs{})
@ JuMP /tmp/ar_julia_depot/packages/JuMP/7eD71/src/optimizer_interface.jl:609
[7] optimize!(model::Model)
@ JuMP /tmp/ar_julia_depot/packages/JuMP/7eD71/src/optimizer_interface.jl:560
[8] top-level scope
@ REPL[35]:1
Some type information was truncated. Use `show(err)` to see complete types.
julia>using JuMP
julia>import ParametricOptInterface as POI
julia>import Clarabel
julia>begin
inner = MOI.instantiate(Clarabel.Optimizer; with_bridge_type = Float64, with_cache_type = Float64)
model =direct_model(POI.Optimizer(inner))
set_silent(model)
@variable(model, x >=0)
@variable(model, p inParameter(1.0))
@constraint(model, x == p)
optimize!(model)
set_parameter_value(p, 2.0)
optimize!(model)
end
ERROR: MathOptInterface.SetAttributeNotAllowed{MathOptInterface.ConstraintSet}:## Cause
Setting attribute MathOptInterface.ConstraintSet() cannot be performed
## Fixing this error
An `MOI.NotAllowedError` error occurs when you have tried to do something that
is not implemented by the solver.
The most common way to fix this error is to wrap the optimizer in a
`MOI.Utilities.CachingOptimizer`.
For example, if you are using`JuMP.Model` or `JuMP.set_optimizer`, do:```juliamodel = JuMP.Model(optimizer; with_cache_type = Float64)model = JuMP.GenericModel{T}(optimizer; with_cache_type = T)JuMP.set_optimizer(model, optimizer; with_cache_type = Float64)```
Similarly, if you are using`MOI.instantiate`, do:```juliamodel = MOI.instantiate(optimizer; with_cache_type = Float64)```
Stacktrace:
[1] set(b::MathOptInterface.Bridges.LazyBridgeOptimizer{…}, attr::MathOptInterface.ConstraintSet, ci::MathOptInterface.ConstraintIndex{…}, set::MathOptInterface.EqualTo{…})
@ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/Q3V1z/src/Bridges/bridge_optimizer.jl:1585
[2] _update_affine_constraints!(model::ParametricOptInterface.Optimizer{…}, affine_constraint_cache_inner::MathOptInterface.Utilities.DoubleDicts.DoubleDictInner{…}, affine_constraint_cache_set_inner::MathOptInterface.Utilities.DoubleDicts.DoubleDictInner{…})
@ ParametricOptInterface ~/.julia/packages/ParametricOptInterface/qeWEl/src/update_parameters.jl:63
[3] _update_affine_constraints!(model::ParametricOptInterface.Optimizer{…})
@ ParametricOptInterface ~/.julia/packages/ParametricOptInterface/qeWEl/src/update_parameters.jl:32
[4] update_parameters!(model::ParametricOptInterface.Optimizer{Float64, MathOptInterface.Bridges.LazyBridgeOptimizer{…}})
@ ParametricOptInterface ~/.julia/packages/ParametricOptInterface/qeWEl/src/update_parameters.jl:293
[5] optimize!(model::ParametricOptInterface.Optimizer{Float64, MathOptInterface.Bridges.LazyBridgeOptimizer{…}})
@ ParametricOptInterface ~/.julia/packages/ParametricOptInterface/qeWEl/src/MOI_wrapper.jl:2068
[6] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::@Kwargs{})
@ JuMP ~/.julia/packages/JuMP/7eD71/src/optimizer_interface.jl:609
[7] optimize!(model::Model)
@ JuMP ~/.julia/packages/JuMP/7eD71/src/optimizer_interface.jl:560
[8] top-level scope
@ REPL[70]:10
Some type information was truncated. Use `show(err)` to see complete types.
So I think the Clarabel issue is that there is a bridge inside the POI.Optimizer.
It works if you move the required bridges outside POI:
using JuMP
import MathOptInterface as MOI
import ParametricOptInterface as POI
using Clarabel
model =Model() do
inner = MOI.instantiate(Clarabel.Optimizer; with_cache_type = Float64)
return POI.Optimizer(inner)
end@variable(model, x >=0)
@variable(model, p in MOI.Parameter(1.0))
@constraint(model, x == p)
@objective(model, Min, x)
optimize!(model)
set_parameter_value(p, 2.0)
optimize!(model)
I think these are all related to the fact that the parameter constraints are scalars, so they're getting bridged and modified in weird orders.
I have a bad memory, but I think this was done because, at the time, we couldn't change multiple constants with MOI at once right? if this is no longer the case, should I try to update POI?
julia>using JuMP, SCS
julia>import ParametricOptInterface as POI
julia> model = MOI.Bridges.full_bridge_optimizer(
POI.Optimizer(SCS.Optimizer),
Float64,
)
MOIB.LazyBridgeOptimizer{ParametricOptInterface.Optimizer{Float64, MOIU.CachingOptimizer{SCS.Optimizer, MOIU.UniversalFallback{MOIU.Model{Float64}}}}}
├ Variable bridges: none
├ Constraint bridges: none
├ Objective bridges: none
└ model: ParametricOptInterface.Optimizer{Float64, MOIU.CachingOptimizer{SCS.Optimizer, MOIU.UniversalFallback{MOIU.Model{Float64}}}}
├ ObjectiveSense: FEASIBILITY_SENSE
├ ObjectiveFunctionType: MOI.ScalarAffineFunction{Float64}
├ NumberOfVariables:0
└ NumberOfConstraints:0
julia> x = MOI.add_variable(model)
MOI.VariableIndex(1)
julia> p, _ = MOI.add_constrained_variable(model, MOI.Parameter(1.0))
(MOI.VariableIndex(4611686018427387905), MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.Parameter{Float64}}(4611686018427387905))
julia> f = MOI.Utilities.vectorize([x, 1.0* p, x])
┌ ┐
│0.0+1.0 MOI.VariableIndex(1) │
│0.0+1.0 MOI.VariableIndex(4611686018427387905)│
│0.0+1.0 MOI.VariableIndex(1) │
└ ┘
julia> MOI.add_constraint(model, f, MOI.PositiveSemidefiniteConeTriangle(2))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64}, MathOptInterface.PositiveSemidefiniteConeTriangle}(2)
julia> MOI.optimize!(model)
------------------------------------------------------------------
SCS v3.2.11- Splitting Conic Solver
(c) Brendan O'Donoghue, Stanford University, 2012------------------------------------------------------------------
problem: variables n:1, constraints m:3
cones: s: psd vars:3, ssize:1
settings: eps_abs:1.0e-04, eps_rel:1.0e-04, eps_infeas:1.0e-07
alpha:1.50, scale:1.00e-01, adaptive_scale:1
max_iters:100000, normalize:1, rho_x:1.00e-06
acceleration_lookback:10, acceleration_interval:10
compiled with openmp parallelization enabled
lin-sys: sparse-direct-amd-qdldl
nnz(A):2, nnz(P):0------------------------------------------------------------------
iter | pri res | dua res | gap | obj | scale | time (s)
------------------------------------------------------------------0|1.00e+003.00e-013.00e-011.50e-011.00e-012.07e-0425|4.71e-088.69e-170.00e+000.00e+001.00e-012.91e-04------------------------------------------------------------------
status: solved
timings: total:2.95e-04s = setup:6.52e-05s + solve:2.30e-04s
lin-sys:5.20e-06s, cones:3.07e-05s, accel:9.54e-07s
------------------------------------------------------------------
objective =0.000000------------------------------------------------------------------
julia> MOI.Bridges.print_active_bridges(model)
* Supported objective: MOI.ScalarAffineFunction{Float64}
ERROR: KeyError: key (MathOptInterface.Parameter{Float64},) not found
Stacktrace:
[1] getindex
@ ~/.julia/packages/OrderedCollections/Xihhq/src/ordered_dict.jl:387 [inlined]
[2] print_active_bridges(io::Base.TTY, b::MathOptInterface.Bridges.LazyBridgeOptimizer{…}, ::Type{…}, ::Type{…}, offset::String)
@ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/Q3V1z/src/Bridges/debug.jl:664
[3] print_active_bridges(io::Base.TTY, b::MathOptInterface.Bridges.LazyBridgeOptimizer{ParametricOptInterface.Optimizer{…}}, ::Type{MathOptInterface.VariableIndex}, ::Type{MathOptInterface.Parameter{…}})
@ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/Q3V1z/src/Bridges/debug.jl:641
[4] print_active_bridges(io::Base.TTY, b::MathOptInterface.Bridges.LazyBridgeOptimizer{ParametricOptInterface.Optimizer{Float64, MathOptInterface.Utilities.CachingOptimizer{…}}})
@ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/Q3V1z/src/Bridges/debug.jl:550
[5] print_active_bridges(::MathOptInterface.Bridges.LazyBridgeOptimizer{ParametricOptInterface.Optimizer{Float64, MathOptInterface.Utilities.CachingOptimizer{…}}})
@ MathOptInterface.Bridges ~/.julia/packages/MathOptInterface/Q3V1z/src/Bridges/debug.jl:556
[6] top-level scope
@ REPL[74]:1
Some type information was truncated. Use `show(err)` to see complete types.
This function makes an incorrect assumption for the case where F==VariableIndex and we support add_constrained_variable(model, ::S) but not add_constraint(model, ::F, ::S):
By making sure the solvers use the geometric form (which is also the direction mosek is taking), we shouldn't have variables bridges. Here, there are probably two equivalent way to reformulate of equal bridging cost and one of them with variable bridges. Maybe we should only use variable bridges only if the cost is strictly smaller that without variable bridges ?
Activity
[-]POI Failing with SCS[/-][+]POI Failing with SCS and Clarabel[/+]andrewrosemberg commentedon Feb 12, 2026
Actually also happening with Clarabel:
The error:
andrewrosemberg commentedon Feb 12, 2026
I first saw this using DiffOpt:
odow commentedon Feb 12, 2026
Here's the full error for SCS. We're not triggering the cache rebuild because we hit a MethodError instead of a NotAllowedError.
odow commentedon Feb 12, 2026
The Clarabel one is slightly different
odow commentedon Feb 12, 2026
I think these are all related to the fact that the parameter constraints are scalars, so they're getting bridged and modified in weird orders.
odow commentedon Feb 12, 2026
Okay. I've fixed the SCS error: jump-dev/SCS.jl#342
The Clarabel issue seems to be jump-dev/MathOptInterface.jl#2472. I'll take a better look.
odow commentedon Feb 12, 2026
So I think the Clarabel issue is that there is a bridge inside the POI.Optimizer.
It works if you move the required bridges outside POI:
So then POI+Clarabel are operating on this model:
andrewrosemberg commentedon Feb 13, 2026
I have a bad memory, but I think this was done because, at the time, we couldn't change multiple constants with MOI at once right? if this is no longer the case, should I try to update POI?
[-]POI Failing with SCS and Clarabel[/-][+]POI failing with Clarabel[/+]odow commentedon Feb 17, 2026
The SCS issue had been hiding from us because of
ParametricOptInterface.jl/test/Project.toml
Line 15 in 1c62131
I'm taking a look.
odow commentedon Feb 18, 2026
I found the cause of our problems:
This function makes an incorrect assumption for the case where
F==VariableIndexand we supportadd_constrained_variable(model, ::S)but notadd_constraint(model, ::F, ::S):https://github.com/jump-dev/MathOptInterface.jl/blob/b12036d7798d3a7cc685de9b3a3989e35b841066/src/Bridges/lazy_bridge_optimizer.jl#L456-L462
I need to think about this more.
odow commentedon Feb 19, 2026
This is a rabbit hole. I'm just going all over the place: jump-dev/Ipopt.jl#528
I think this is also just a combination of bugs in
print_active_bridges. PR in the works.joaquimg commentedon Mar 23, 2026
@odow Do you have an update on this?
odow commentedon Mar 23, 2026
No, I fixed the
print_active_bridges, but not the underlying failure withMOI.set(model, MOI.ConstraintSet(), ...)The offending line is:
https://github.com/jump-dev/MathOptInterface.jl/blob/b5778d01ec690e5514630ff2a2fe51ae0bd480f0/src/Bridges/bridge_optimizer.jl#L1570-L1586
blegat commentedon Mar 24, 2026
Which variable bridge is being used ? I don't expect Clarabel to use variable bridges since it uses the geometric conic form (aka image form)
odow commentedon Mar 25, 2026
It uses https://github.com/jump-dev/MathOptInterface.jl/blob/master/src/Bridges/Variable/bridges/VectorizeBridge.jl
I really wonder if that bridge was a mistake sometimes. It adds so much complexity all over the place.
blegat commentedon Mar 25, 2026
By making sure the solvers use the geometric form (which is also the direction mosek is taking), we shouldn't have variables bridges. Here, there are probably two equivalent way to reformulate of equal bridging cost and one of them with variable bridges. Maybe we should only use variable bridges only if the cost is strictly smaller that without variable bridges ?
odow commentedon Mar 25, 2026
Let me take a look. I would be super keen for this.