{"record":{"id":"5084ea62f7a253e2","repo":"passbolt/passbolt_api","slug":"customized-v3-directory-sync-settings-fields-mapping-are-not","errorCode":null,"errorMessage":"Customized v3 directory sync settings fields mapping are not supported: ","messagePattern":"Customized v3 directory sync settings fields mapping are not supported: ","errorType":"exception","errorClass":"UnexpectedValueException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltEe/DirectorySync/src/Service/DirectorySettings/FixDirectorySyncLegacyFieldsMappingService.php","lineNumber":119,"sourceCode":"\n        if (\n            !$value\n            || !is_array($value)\n            || !isset($value['fieldsMapping'])\n            || count($value['fieldsMapping']) !== 2\n        ) {\n            $errorMessage = \"Directory settings are invalid: {$directorySyncSettings->value}\";\n            throw new UnexpectedValueException($errorMessage);\n        }\n\n        $fieldsMapping = $value['fieldsMapping'];\n        $legacyFieldsMapping = self::getLegacyFieldsMapping();\n        $v3DiffFieldsMapping = array_diff(Hash::flatten($fieldsMapping), Hash::flatten($legacyFieldsMapping));\n\n        if (!empty($v3DiffFieldsMapping)) {\n            $errorMessage = 'Customized v3 directory sync settings fields mapping are not supported: ';\n            $errorMessage .= $directorySyncSettings->value;\n            throw new UnexpectedValueException($errorMessage);\n        }\n\n        return $value;\n    }\n\n    /**\n     * Fixes fields mapping in the database for those who upgraded from v3 to v4.\n     *\n     * @return bool True if the settings where fixed, false otherwise.\n     * @throws \\UnexpectedValueException If directory settings stored are invalid and cannot be parsed\n     * @throws \\Cake\\ORM\\Exception\\PersistenceFailedException When the settings couldn't be saved\n     * @throws \\Exception If the migration V400ChangeLdapServersConfigKey format is invalid or not found\n     * @throws \\UnexpectedValueException If the directory sync settings are invalid\n     */\n    public function fix(): bool\n    {\n        $directorySyncSettings = $this->findDirectorySyncSettings();\n","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/DirectorySync/src/Service/DirectorySettings/FixDirectorySyncLegacyFieldsMappingService.php#L101-L137","documentation":"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.","triggerScenarios":"Running fix() for settings created under v3 where the stored fieldsMapping differs in any flattened key/value from FixDirectorySyncLegacyFieldsMappingService::getLegacyFieldsMapping().","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"$decoded = json_decode($settings->value, true);\n$diff = array_diff(Hash::flatten($decoded['fieldsMapping'] ?? []), Hash::flatten(FixDirectorySyncLegacyFieldsMappingService::getLegacyFieldsMapping()));\n$isDefaultMapping = empty($diff);","typeGuard":null,"tryCatchPattern":"try {\n    (new FixDirectorySyncLegacyFieldsMappingService())->fix();\n} catch (UnexpectedValueException $e) {\n    // custom v3 mapping detected — reconfigure mapping manually in v4 admin UI\n}","preventionTips":["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"],"tags":["passbolt","directory-sync","ldap","fields-mapping","unsupported-customization"],"backgroundTag":"unsupported-config-value","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}