-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Description
Symfony version(s) affected
7.3.5 (regression since 7.3.2)
Description
After upgrading from symfony/serializer v7.3.2 to v7.3.5,
the ObjectNormalizer started producing different field names for boolean getters.
Before the update, a getter like isAuthorized() produced the field authorized.
After the update, the field became isAuthorized.
This change silently breaks serialized API responses and introduces a backward-incompatible change between patch versions, which is unexpected and potentially critical for projects with stable API contracts.
How to reproduce
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
final class PartnerAuthorizationInfo
{
public function __construct(
private bool $isAuthorized = false,
) {}
public function isAuthorized(): bool
{
return $this->isAuthorized;
}
}
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
echo $serializer->serialize(new PartnerAuthorizationInfo(true), 'json');Output before (v7.3.2)
{"authorized": true}Output after (v7.3.5)
{"isAuthorized": true}Expected behavior
Boolean getters using the is* pattern should produce property names without the is prefix, e.g.:
isAuthorized() → "authorized"
This was the behavior up to 7.3.2 and should remain stable in patch releases.
Actual behavior
Since 7.3.5, the ObjectNormalizer now includes the is prefix in serialized property names, producing:
isAuthorized() → "isAuthorized"
Possible cause
Recent changes in the serializer’s ObjectNormalizer logic around method-to-property name resolution seem to have caused this.
Likely related to or introduced by:
- 61096
- [61097][Serializer] Fix normalizing objects with accessors having the same name as a property #61097
- 61988
Those PRs refactored the internal handling of accessors and may have altered how is* accessors map to property names.
Why this is problematic
- Introduces breaking API changes even in patch-level updates.
- Affects any DTOs or models with boolean
is*accessors. - Causes inconsistencies between environments running slightly different patch versions.
- Breaks compatibility with existing clients relying on the previous field names.
Suggested resolution
- Restore previous behavior for boolean
is*accessors (isAuthorized()→"authorized"). - If the new behavior is intentional, introduce an explicit configuration flag to opt into it.
- Maintain backward compatibility for serialization naming in patch versions.
Environment
| Component | Version |
|---|---|
| PHP | 8.3 |
| symfony/serializer | 7.3.5 |
| symfony/framework-bundle | 7.3.5 |
| Configuration | Default (no custom name converter) |
Additional context
This issue appeared immediately after upgrading an existing production project from v7.3.2 to v7.3.5.
No configuration or code changes were made — only dependency updates via Composer.
This regression can have a significant impact in API-based applications where serialized DTO field names are part of a public contract.