bitwarden/server · error · BadRequestException
All existing folders must be included in the rotation.
Error message
All existing folders must be included in the rotation.
What it means
Thrown by FolderRotationValidator during key rotation. It loads every folder the user owns and requires the rotation request to include each one matched by Id, because each folder's name is encrypted with the user key. A missing folder would remain under the old key and become unreadable, so the whole rotation is rejected.
Source
Thrown at src/Api/KeyManagement/Validators/FolderRotationValidator.cs:33
_folderRepository = folderRepository;
}
public async Task<IEnumerable<Folder>> ValidateAsync(User user, IEnumerable<FolderWithIdRequestModel> folders)
{
var result = new List<Folder>();
var existingFolders = await _folderRepository.GetManyByUserIdAsync(user.Id);
if (existingFolders == null || existingFolders.Count == 0)
{
return result;
}
foreach (var existing in existingFolders)
{
var folder = folders.FirstOrDefault(c => c.Id == existing.Id);
if (folder == null)
{
throw new BadRequestException("All existing folders must be included in the rotation.");
}
result.Add(folder.ToFolder(existing));
}
return result;
}
}
View on GitHub (pinned to e93b962371)
Solutions
- Sync/refresh the vault so the client knows about all folders immediately before building the rotation request.
- Include every folder Id the user has, re-encrypted with the new key.
- Delete any unwanted folders before rotating rather than omitting them from the rotation list.
- Validate the submitted folder Id set is a superset of the server folder set before sending.
Example fix
// before
const folders = localVault.folders.map(f => ({ id: f.id, name: reencrypt(f.name) }));
// after
await vault.sync();
const folders = vault.folders.map(f => ({ id: f.id, name: reencrypt(f.name) })); Defensive patterns
Strategy: validation
Validate before calling
const folders = await api.getFolders();
const submitted = new Set(payload.folders.map(f => f.id));
const missing = folders.filter(f => !submitted.has(f.id));
if (missing.length) {
throw new Error(`Rotation is missing folders: ${missing.map(f => f.id).join(', ')}`);
} Type guard
function isCompleteFolderRotation(existing: { id: string }[], submitted: { id: string }[]): boolean {
const have = new Set(submitted.map(s => s.id));
return existing.every(f => have.has(f.id));
} Try / catch
try {
await api.rotateKey(payload);
} catch (e) {
if (e.status === 400 && /folders must be included/i.test(e.message)) {
await vault.sync();
payload.folders = vault.folders.map(f => ({ id: f.id, name: reencrypt(f.name) }));
return api.rotateKey(payload);
}
throw e;
} Prevention
- Sync the vault immediately before constructing the rotation payload.
- Delete unwanted folders before rotating rather than omitting them.
- Assert the submitted folder ids cover every server folder.
When it happens
Trigger: Key-rotation request whose folders array omits a Folder.Id that exists for the user. A folder was created in another session after the client cached the folder list; the client sent a partial list; an Id was malformed.
Common situations: User created a folder on another device/client and then rotated keys here; client enumerated folders from local vault state that was out of sync; a sync race during rotation.
Related errors
- All existing trusted devices must be included in the rotatio
- All existing emergency access keys must be included in the r
- All existing reset password keys must be included in the rot
- All existing sends must be included in the rotation.
- All existing webauthn prf keys must be included in the rotat
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/02c02e2180ac5642.
Report an issue: GitHub.