passbolt/passbolt_api · error · UnexpectedValueException

Directory settings are invalid:

Error message

Directory settings are invalid: 

What it means

getAndAssertDirectorySyncDefaultV3FieldsMapping decodes the stored directory-sync organization setting JSON and requires it to contain a fieldsMapping array of exactly 2 entries (ad and openldap). If the JSON is empty, not an array, missing fieldsMapping, or has the wrong count, it throws this UnexpectedValueException including the raw stored value. It protects the v3→v4 mapping fix from corrupt or unexpected settings.

Solutions

  1. Inspect the stored value: SELECT value FROM organization_settings WHERE property = 'directory-sync'; and confirm the JSON structure.
  2. Re-save the directory sync settings from the passbolt admin UI (or via the settings API) to regenerate a valid payload with default fieldsMapping.
  3. If the row is unrecoverable, delete it and reconfigure LDAP sync from scratch.
  4. Only run the legacy-mapping fix on installs whose settings actually date from v3 (see isDirectorySyncSettingsCreatedWithV3).
Defensive patterns

Strategy: validation

Validate before calling

$raw = $settings->value;
$decoded = json_decode($raw, true);
$valid = $decoded && is_array($decoded) && isset($decoded['fieldsMapping']) && count($decoded['fieldsMapping']) === 2;

Type guard

$hasDefaultFieldsMapping = fn(?OrganizationSetting $s): bool =>
    $s && ($v = json_decode($s->value, true)) && is_array($v)
    && isset($v['fieldsMapping']) && is_array($v['fieldsMapping']) && count($v['fieldsMapping']) === 2;

Try / catch

try {
    (new FixDirectorySyncLegacyFieldsMappingService())->fix();
} catch (UnexpectedValueException $e) {
    // stored settings are corrupt/malformed — re-save settings from admin UI
}

Prevention

When it happens

Trigger: Running FixDirectorySyncLegacyFieldsMappingService::fix() when the organization_settings row for directory sync holds JSON that is falsy, non-array, lacks a 'fieldsMapping' key, or has fieldsMapping with a count other than 2.

Common situations: Settings row truncated or hand-edited directly in the database; legacy (pre-fieldsMapping) settings format from very old passbolt versions; corrupted JSON from a failed save; importing settings from another instance.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/3f580fd6353ebfa4. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/DirectorySync/src/Service/DirectorySettings/FixDirectorySyncLegacyFieldsMappingService.php:109

    /**
     * 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
            || !is_array($value)
            || !isset($value['fieldsMapping'])
            || count($value['fieldsMapping']) !== 2
        ) {
            $errorMessage = "Directory settings are invalid: {$directorySyncSettings->value}";
            throw new UnexpectedValueException($errorMessage);
        }

        $fieldsMapping = $value['fieldsMapping'];
        $legacyFieldsMapping = self::getLegacyFieldsMapping();
        $v3DiffFieldsMapping = array_diff(Hash::flatten($fieldsMapping), Hash::flatten($legacyFieldsMapping));

        if (!empty($v3DiffFieldsMapping)) {
            $errorMessage = 'Customized v3 directory sync settings fields mapping are not supported: ';
            $errorMessage .= $directorySyncSettings->value;
            throw new UnexpectedValueException($errorMessage);
        }

        return $value;
    }

    /**
     * Fixes fields mapping in the database for those who upgraded from v3 to v4.
     *

View on GitHub (pinned to 31c1bbc10f)