Why does passing an instance of IlluminateHttpUploadedFile to a custom cast result in an infinite loop?

I have a Configuration model in which I have implemented a custom cast, the getter works perfectly but let’s look at the setter.

For clarity, I have trimmed down the code samples to only what’s relevant to the context.

App/Models/Configuration.php

use IlluminateDatabaseEloquentModel;

class Configuration extends Model
{ 
    protected function casts(): array
    {
        return [
            'value' => AppCastsConfigValue::class,
        ];
    }
}

App/Casts/ConfigValue.php

use IlluminateContractsDatabaseEloquentCastsAttributes;
use IlluminateDatabaseEloquentModel;
use IlluminateHttpUploadedFile;

class ConfigValue implements CastsAttributes
{ 
    public function set(Model $model, string $key, mixed $value, array $attributes): mixed
    { 
        $saveable = $value instanceof UploadedFile || 
                     (isset($value[0]) && $value[0] instanceof UploadedFile);

        echo 1; // Take note of this

        return match (true) {
            ...// Other conditions
            $saveable => $this->doUpload(UploadedFile|array $value),
            ...// Other conditions
            default => (string) $value,
        };
    }
}

Let’s also not bother about the logic for the file uploads, the problem here is that X-Debug throws an infinite loop error after terminating the script when proccessing the upload. But if I straight out return the output, you can see from the image below that the script is run several times before it returns the response, adding upload logic to this ends us in an infinite loop.

example response from postman, here you can see that 1 is being outputed several times.

App/Controllers/ConfigController.php

$config = Configuration::where('key', $key)->first();

$config->value = $value;
$config->save();

On the Controller $key and $value are from a foreach loop of $request->configurations, the above works well when $value is anything but an instance of IlluminateHttpUploadedFile in which case we fall into the infinite loop.

What am I doing wrong here?