Repository navigation
V5 folder creation fails when Log plugin validates folder history #617
Description
- API: Community Edition 5.14.3 (
passbolt/passbolt:5.14.3-1-ce) - Environment
- Operating system: official Docker image, Debian GNU/Linux 13
- PHP: 8.4.24
- Web server: nginx 1.26.3
- Database server: MariaDB 10.11.18
What you did?
With the standard Metadata, Folders, and Log plugins enabled, I authenticated normally and attempted to create a personal metadata-v5 folder through:
POST /folders.json?api-version=v2
The request used the same v5 shape exercised by MetadataFoldersCreateControllerTest:
{
"metadata": "<valid encrypted PASSBOLT_FOLDER_METADATA message>",
"metadata_key_id": "<valid metadata key UUID>",
"metadata_key_type": "user_key",
"folder_parent_id": null
}No plaintext name was supplied. MetadataFolderDto treats this as a v5 payload and rejects mixing a non-null v4 name with v5 metadata.
Reproduction outline:
- Enable v5 metadata settings and leave the standard Folders and Log plugins enabled.
- Authenticate a valid user through the normal Passbolt authentication flow.
- Produce valid encrypted and signed
PASSBOLT_FOLDER_METADATAfor the user's metadata key. - POST the request above to
/folders.json?api-version=v2. - Inspect the API response and aggregate database state.
No private URL, account identity, credential, OpenPGP fingerprint, remote object identifier, or ciphertext is included in this report.
What happened?
The endpoint returned HTTP 400 with:
Could not validate folder history data.
The transaction rolled back completely. Aggregate checks immediately after the failure showed:
folders: 0 rows;folders_history: 0 rows;- orphan folder-history rows: 0;
- folders without history rows: 0;
CHECK TABLE folders, folders_history: bothOK.
The causal path appears to be:
MetadataFolderDto::toArray()includesname => nullfor v5 and validates that v4 and v5 metadata fields are not mixed.FolderSaveV5AwareTraitselectsFoldersTable::validationV5(), which removes the v4namevalidation and validates encrypted metadata instead.FoldersCreateServicesaves the folder inside a transaction.- The standard Log plugin handles
Model.afterSave. EntitiesHistoryCreateServicedetects the detailedFoldersHistoryassociation and callsFoldersHistoryTable::create($entity->toArray()).FoldersHistoryTable::validationDefault()still requires a non-empty plaintextname, while its accessible history fields are onlyid,folder_id, andname.FoldersHistoryTable::create()throws the validation exception, rolling back the folder transaction and returning HTTP 400.
This does not appear to be caused by residual or corrupt laboratory data: both tables were empty and healthy after rollback, the application endpoint was healthy, the database container was healthy, and the Passbolt container had zero restarts.
I also reviewed the official v5.14.3...v5.15.0 comparison. v5.15.0 does not change:
plugins/PassboltCe/Folders/src/Model/Table/FoldersHistoryTable.php;plugins/PassboltCe/Log/src/Events/ActionLogsModelListener.php;plugins/PassboltCe/Log/src/Service/EntitiesHistory/EntitiesHistoryCreateService.php.
The v5.15.0 release notes do not identify a corresponding folder-history fix.
What you expected to happen?
- HTTP 2xx for a valid metadata-v5 folder request.
- Atomic persistence of the v5 folder, owner permission, and optional folder relation.
- Successful audit/history recording without requiring a plaintext folder name that is intentionally absent from v5 metadata.
- A response containing the new folder identifier and v5 metadata fields.
Because the server cannot generally decrypt personal v5 folder metadata to reconstruct a plaintext name, a fix should preserve audit semantics without disabling the Log plugin or requiring clients to send both v4 and v5 metadata.
A regression test could enable Metadata, Folders, and Log together, establish the real FoldersCreate.create UserAction context, create personal root and child v5 folders without plaintext name, and assert both the HTTP success and internal consistency of the action log/history representation.
Relevant public sources:
- https://github.com/passbolt/passbolt_api/blob/v5.14.3/plugins/PassboltCe/Metadata/src/Model/Dto/MetadataFolderDto.php
- https://github.com/passbolt/passbolt_api/blob/v5.14.3/plugins/PassboltCe/Metadata/src/Utility/Folders/FolderSaveV5AwareTrait.php
- https://github.com/passbolt/passbolt_api/blob/v5.14.3/plugins/PassboltCe/Folders/src/Model/Table/FoldersTable.php
- https://github.com/passbolt/passbolt_api/blob/v5.14.3/plugins/PassboltCe/Folders/src/Model/Table/FoldersHistoryTable.php
- https://github.com/passbolt/passbolt_api/blob/v5.14.3/plugins/PassboltCe/Log/src/Events/ActionLogsModelListener.php
- https://github.com/passbolt/passbolt_api/blob/v5.14.3/plugins/PassboltCe/Log/src/Service/EntitiesHistory/EntitiesHistoryCreateService.php
- v5.14.3...v5.15.0
Activity
pbottero commentedon Oct 13, 2026
Confirming this is still present in passbolt CE 5.16.0 (docker 5.16.0-1-ce-non-root).
It is not limited to personal folders: with zero-knowledge metadata key sharing and only v5 types allowed, a v5 folder encrypted with the shared metadata key (metadata_key_type: shared_key) fails the same way, with {"name":{"_required":"A name is required."}}.
We are carrying a local patch until this is merged. The approach in #618 (nullable folders_history.name, a v5 validator, v4 still requiring a name) would let us drop it. Tested on our side with the patch in and out on the same database: v5 folders, shared and personal, are created and the history row is written; v4 is still rejected.