Parameter updates get lost between controller and processor using performEdit

Here is the code called from the Controller when setting a parameter from any of my UI widgets (slider, button, …):

// Notify a parameter changed -----
        
if(setParamNormalized(tag, value) != Steinberg::kResultOk) {
    printf("Fail to call set param normalized in Controller::SetParameter\n");
    return false;
}

// Transmit value to host -----

EditController::beginEdit(tag);
Steinberg::tresult result = EditController::performEdit(tag, getParamNormalized(tag));
EditController::endEdit(tag);

if(result != Steinberg::kResultOk) {
    printf("Perform Edit failed, param: %d, value: %f\n", paramId, value);
    return false;
}

From the Processor process() method:

Steinberg::int32 num_params_changed = data.inputParameterChanges->getParameterCount();
            
// Process each param
for(Steinberg::int32 index = 0; index < num_params_changed; ++index) {
    
    Steinberg::Vst::IParamValueQueue* paramQueue = data.inputParameterChanges->getParameterData(index);
    
    if(!paramQueue) {
        continue;
    }
    
    uint32_t param_id = paramQueue->getParameterId();
    Steinberg::int32 num_points = paramQueue->getPointCount();
    
    // Process each param value change
    for(Steinberg::int32 point=0; point < num_points; ++point) {
        
        Steinberg::Vst::ParamValue value = 0.f;
        Steinberg::int32 sampleOffset = 0;
        
        if(paramQueue->getPoint(point, sampleOffset, value) == Steinberg::kResultTrue) {
            if(param_id >= mParamIdToEngineParamIndexTable.size()) {
                printf("ERROR: out of range param id: %d\n", param_id);
                continue;
            }
            
            uint32_t engine_param_idx = mParamIdToEngineParamIndexTable[param_id];
            mAudioEngine->SetParameter(engine_param_idx, static_cast<float>(value));
        }
    }
}

These are directly inspired from the samples included in the VST3 SDK public.sdk section.
Am i doing something wrong here ?