doctrine/orm · error · InvalidArgumentException
Field "%s" is not a valid field of the entity "%s" in PreUpd
Error message
Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.
What it means
InvalidArgumentException from PreUpdateEventArgs::assertValidField() (src/Event/PreUpdateEventArgs.php:93). getOldValue()/getNewValue()/setNewValue() only work with fields present in the entity's change set — the UnitOfWork computes changes before the PreUpdate event, and the args object wraps that computed change set. Asking for a field that was not changed (or does not exist) fails this assertion.
Source
Thrown at src/Event/PreUpdateEventArgs.php:93
/**
* Sets the new value of this field.
*/
public function setNewValue(string $field, mixed $value): void
{
$this->assertValidField($field);
$this->entityChangeSet[$field][1] = $value;
}
/**
* Asserts the field exists in changeset.
*
* @throws InvalidArgumentException
*/
private function assertValidField(string $field): void
{
if (! isset($this->entityChangeSet[$field])) {
throw new InvalidArgumentException(sprintf(
'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
$field,
get_debug_type($this->getObject()),
));
}
}
}
View on GitHub (pinned to d9b9ff7301)
Solutions
- Guard every access with $args->hasChangedField($field) before calling getOldValue/getNewValue/setNewValue.
- If you must touch a field that is not part of the change set, mutate the entity and register it manually: $entity->setUpdatedAt(...); plus $args->setNewValue only for changed fields — or recompute via $em->getUnitOfWork()->computeChangeSet($args->getObject()).
- Double-check field spelling and case against the mapping (the exception prints the actual entity class).
- Avoid setting a value identical to the current one; the UnitOfWork will not mark it changed, so your guard matters.
Example fix
// before
public function preUpdate(PreUpdateEventArgs $args): void {
$args->setNewValue('updatedAt', new DateTimeImmutable());
// throws if 'updatedAt' itself did not change
}
// after
public function preUpdate(PreUpdateEventArgs $args): void {
$entity = $args->getObject();
$entity->setUpdatedAt(new DateTimeImmutable());
// only inspect change-set fields through $args:
if ($args->hasChangedField('status')) {
$old = $args->getOldValue('status');
// ...
}
$em = $args->getObjectManager();
$em->getUnitOfWork()->recomputeSingleEntityChangeSet(
$em->getClassMetadata($entity::class), $entity
);
} Defensive patterns
Strategy: validation
Validate before calling
if ($args->hasChangedField('status')) {
$old = $args->getOldValue('status');
$args->setNewValue('status', $newValue);
} Try / catch
try {
$old = $args->getOldValue($field);
} catch (\InvalidArgumentException $e) {
// field not in this flush's change set — treat as 'no previous value'
$old = null;
} Prevention
- Always gate getOldValue/getNewValue/setNewValue with hasChangedField().
- Set audit columns on the entity itself and recompute the change set, instead of setNewValue on unchanged fields.
- Keep listener field names in sync with mappings; add tests that flush unrelated-field changes.
When it happens
Trigger: Inside a preUpdate listener calling $args->setNewValue('status', ...) or $args->getOldValue('status') when 'status' is not in the change set: the new value equals the old one (field unchanged), the field name is misspelled/case-wrong, or you read fields of a related entity instead of the updated one. Also calling setNewValue for a field never set on the entity.
Common situations: Listeners that unconditionally do $args->setNewValue("updatedAt", new DateTime()) even when only unrelated columns changed; renaming entity fields without updating listeners; assuming getOldValue works for any field rather than only changed ones; comparing values with != so a no-op change reaches the listener.
Related errors
- Uninitialized result set mapping.
- Unable to use access strategy type of [%s] without a Concurr
- Unrecognized access strategy type [%s]
- If you want to use a "READ_WRITE" cache an implementation of
- The directory "%s" does not exist and could not be created.
AI-assisted analysis of doctrine/orm@d9b9ff7301 (2026-08-21).
Data as JSON: /api/errors/dc45a8ca1b2d6656.
Report an issue: GitHub.