Quick answer: Unreal Gameplay Ability System attribute (Health, Stamina) going out of range despite a clamp in PreAttributeChange? PreAttributeChange runs before modification; you must also clamp post-execute.

Health dips below 0 from a damage hit. PreAttributeChange clamps to 0..MaxHealth but the modifier still subtracts past it.

PreAttributeChange Limits

PreAttributeChange is called when an attribute is about to change. You modify NewValue in place. It clamps the modifier, but later instant modifications still bypass with PostGameplayEffectExecute paths.

Override PostGameplayEffectExecute

void UMyAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) {
    if (Data.EvaluatedData.Attribute == GetHealthAttribute()) {
        SetHealth(FMath::Clamp(GetHealth(), 0.0f, GetMaxHealth()));
    }
}

Runs after modification — clamp the actual stored value.

Both Levels

Implement both for robust clamping: PreAttributeChange covers immediate / continuous mods; PostGameplayEffectExecute covers instant GameplayEffects.

Replication

For replicated attributes, ensure the clamp happens on authority before replication. Clients can’t fix bad values they receive.

Verifying

Health stays in [0, MaxHealth] under any sequence of damage and heals. No negative or over-max values reach gameplay code.

“Clamp in both PreAttributeChange and PostGameplayEffectExecute. Otherwise attributes leak past bounds.”

Snapshot attribute values in dev builds — an alarm on out-of-range values catches the missing clamp the day it’s introduced.