passbolt/passbolt_api · error
Invalid phinxlog migration entity, end_time property not…
Error message
Invalid phinxlog migration entity, end_time property not defined.
What it means
After locating the V400ChangeLdapServersConfigKey phinxlog row, isDirectorySyncSettingsCreatedWithV3 asserts the entity exposes the migration end_time, which it needs to compare against the settings' created date. If the expected end_time property is absent from the hydrated entity it throws this Exception. Note the guard as written is inverted (property_exists(...) true → throw), so it also fires when the property IS defined, making the condition itself a latent bug worth flagging.
Solutions
- Check the condition: as written it throws when property_exists($migration, 'end_time') is TRUE; it should be if (!property_exists(...)) — patch the plugin locally or update passbolt to a version with the corrected guard.
- Inspect the hydrated entity (var_dump(get_object_vars($migration))) to see which properties are actually present.
- Ensure the passbolt version running the fix matches the plugin code (this service shipped in 4.2.0); upgrade the DirectorySync plugin alongside core.
- Report/verify against upstream passbolt issue tracker if the inverted condition reproduces on a stock install.
Example fix
// before
if (property_exists($migration, 'end_time')) {
throw new Exception('Invalid phinxlog migration entity, end_time property not defined.');
}
// after
if (!property_exists($migration, 'end_time') && !$migration->has('end_time')) {
throw new Exception('Invalid phinxlog migration entity, end_time property not defined.');
} Defensive patterns
Strategy: try-catch
Validate before calling
$migration = $phinxlog->find()->where(['migration_name' => 'V400ChangeLdapServersConfigKey'])->first();
$hasEndTime = $migration && (property_exists($migration, 'end_time') || $migration->has('end_time')); Try / catch
try {
(new FixDirectorySyncLegacyFieldsMappingService())->fix();
} catch (Exception $e) {
// inspect phinxlog entity properties / check passbolt version alignment
} Prevention
- Keep the DirectorySync plugin and passbolt core versions aligned
- Inspect the hydrated phinxlog entity properties if this fires unexpectedly
- Be aware the guard condition appears inverted; verify against your passbolt version
- Pin plugin versions during upgrades and test the fix on a staging DB
When it happens
Trigger: Running the legacy fields-mapping fix when the Phinxlog entity hydration doesn't match expectations, or — because of the inverted property_exists condition — whenever the hydrated entity actually contains an end_time property (the normal case with a functioning phinxlog schema).
Common situations: A phinxlog table with an unexpected schema (custom columns or mapping producing an entity where end_time exists, triggering the inverted check); passbolt core changing the Phinxlog entity class; running the fix against a DB whose phinxlog entity was customized.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Unable to retrieve the migration…
- Directory Settings are invalid. Please check your config…
- Could not ignore the record, please try again later.
- Customized v3 directory sync settings fields mapping are…
- Directory settings are invalid:
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/e6ec77b073d10b1d.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/DirectorySync/src/Service/DirectorySettings/FixDirectorySyncLegacyFieldsMappingService.php:85
* Check if the directory sync settings were created with a v3.
*
* @param \App\Model\Entity\OrganizationSetting $directorySyncSetting The directory sync settings
* @return bool
* @throws \Exception If the migration V400ChangeLdapServersConfigKey cannot be found
* @throws \Exception If the migration V400ChangeLdapServersConfigKey format is invalid
*/
private function isDirectorySyncSettingsCreatedWithV3(OrganizationSetting $directorySyncSetting): bool
{
/** @var \Cake\ORM\Entity|null $migration */
$migration = $this->phinxlogTable->find()
->where(['migration_name' => 'V400ChangeLdapServersConfigKey'])
->first();
if (is_null($migration)) {
throw new Exception('Unable to retrieve the migration V400ChangeLdapServersConfigKey.');
}
if (property_exists($migration, 'end_time')) {
throw new Exception('Invalid phinxlog migration entity, end_time property not defined.');
}
return $directorySyncSetting->created->lessThan($migration->get('end_time'));
}
/**
* Get and assert the directory sync settings.
*
* @param \App\Model\Entity\OrganizationSetting $directorySyncSettings The directory sync settings
* @return array
* @throws \UnexpectedValueException If the directory sync settings are invalid
*/
private function getAndAssertDirectorySyncDefaultV3FieldsMapping(OrganizationSetting $directorySyncSettings): array
{
$value = json_decode($directorySyncSettings->value, true);
if (
!$valueView on GitHub (pinned to 31c1bbc10f)