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

  1. 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.
  2. Inspect the hydrated entity (var_dump(get_object_vars($migration))) to see which properties are actually present.
  3. Ensure the passbolt version running the fix matches the plugin code (this service shipped in 4.2.0); upgrade the DirectorySync plugin alongside core.
  4. 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

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


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 (
            !$value

View on GitHub (pinned to 31c1bbc10f)