passbolt/passbolt_api · error · UnexpectedValueException
Customized v3 directory sync settings fields mapping are…
Error message
Customized v3 directory sync settings fields mapping are not supported:
What it means
The fix only supports directory sync settings whose v3 fieldsMapping exactly matches the known legacy (v3 default) mapping. After flattening both mappings and computing array_diff, any differing value means the admins customized the LDAP attribute mapping in v3 — which the automatic v4 migration cannot translate safely — so it throws this UnexpectedValueException naming the stored value.
Solutions
- Manually migrate: note the custom mapping, then reconfigure the LDAP attribute mapping in the v4 directory sync admin UI.
- Temporarily restore the default v3 fieldsMapping in the DB so fix() can run, then re-apply customizations via the v4 UI.
- Back up the organization_settings row before changing anything.
- Avoid editing fieldsMapping directly in the database; use the admin UI so values stay in a supported format.
Defensive patterns
Strategy: try-catch
Validate before calling
$decoded = json_decode($settings->value, true); $diff = array_diff(Hash::flatten($decoded['fieldsMapping'] ?? []), Hash::flatten(FixDirectorySyncLegacyFieldsMappingService::getLegacyFieldsMapping())); $isDefaultMapping = empty($diff);
Try / catch
try {
(new FixDirectorySyncLegacyFieldsMappingService())->fix();
} catch (UnexpectedValueException $e) {
// custom v3 mapping detected — reconfigure mapping manually in v4 admin UI
} Prevention
- Document any custom LDAP attribute mappings before upgrading to v4
- Compare stored fieldsMapping against getLegacyFieldsMapping() before running fix
- Re-apply customizations through the v4 admin UI instead of the DB
- Back up the organization_settings row before modifying fieldsMapping
When it happens
Trigger: Running fix() for settings created under v3 where the stored fieldsMapping differs in any flattened key/value from FixDirectorySyncLegacyFieldsMappingService::getLegacyFieldsMapping().
Common situations: Admins customized LDAP attribute mapping (e.g. username -> 'sAMAccountName' instead of 'emailAddress') in v3 and then upgraded to v4; settings carried over between instances with different mappings.
Related errors
- Relation creation error: Could not retrieve corresponding…
- group(s) returned by your directory are invalid and will be…
- users returned by your directory are invalid and will be…
- An error has occurred parsing groupCustomFilter
- An error has occurred parsing userCustomFilter
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/5084ea62f7a253e2.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/DirectorySync/src/Service/DirectorySettings/FixDirectorySyncLegacyFieldsMappingService.php:119
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.
*
* @return bool True if the settings where fixed, false otherwise.
* @throws \UnexpectedValueException If directory settings stored are invalid and cannot be parsed
* @throws \Cake\ORM\Exception\PersistenceFailedException When the settings couldn't be saved
* @throws \Exception If the migration V400ChangeLdapServersConfigKey format is invalid or not found
* @throws \UnexpectedValueException If the directory sync settings are invalid
*/
public function fix(): bool
{
$directorySyncSettings = $this->findDirectorySyncSettings();
View on GitHub (pinned to 31c1bbc10f)