monicahq/monica · error · CantBeDeletedException
The module cannot be deleted.
Error message
The module cannot be deleted.
What it means
DestroyModule deletes a template module from the account. Modules shipped or seeded with the template system are marked can_be_deleted = false and must not be removed; when findOrFail locates such a module, CantBeDeletedException aborts the delete before anything is touched.
Source
Thrown at app/Domains/Settings/ManageTemplates/Services/DestroyModule.php:45
{
return [
'author_must_belong_to_account',
'author_must_be_account_administrator',
];
}
/**
* Destroy a module.
*/
public function execute(array $data): void
{
$this->validateRules($data);
$module = $this->account()->modules()
->findOrFail($data['module_id']);
if (! $module->can_be_deleted) {
throw new CantBeDeletedException('The module cannot be deleted.');
}
$module->delete();
}
}
View on GitHub (pinned to e08e917341)
Solutions
- Delete only user-created modules; check the can_be_deleted flag first
- Filter the UI/command to hide or skip modules with can_be_deleted = false
- Check the flag at the call site before invoking the service and show a clear message
Example fix
// before
app(DestroyModule::class)->execute([
'module_id' => $moduleId, // may be a seeded system module -> throws
]);
// after
$module = $account->modules()->findOrFail($moduleId);
if (! $module->can_be_deleted) {
throw ValidationException::withMessages([
'module_id' => 'This module cannot be deleted.',
]);
}
app(DestroyModule::class)->execute(['module_id' => $module->id]); Defensive patterns
Strategy: validation
Validate before calling
// Validate before calling: only deletable modules may be destroyed
$module = $account->modules()->findOrFail($data['module_id']);
if (! $module->can_be_deleted) {
throw ValidationException::withMessages([
'module_id' => 'This module is a system module and cannot be deleted.',
]);
} Type guard
function isDeletableModule(Module $module): bool
{
return $module->can_be_deleted === true;
} Try / catch
use App\Exceptions\CantBeDeletedException;
try {
app(DestroyModule::class)->execute($data);
} catch (CantBeDeletedException $e) {
// deliberate guard: inform the caller this module is protected
throw ValidationException::withMessages(['module_id' => $e->getMessage()]);
} Prevention
- Filter module lists by can_be_deleted before rendering delete actions
- In bulk operations, skip protected modules instead of aborting the run
- Treat can_be_deleted = false as part of the module API surface when building UIs
- Map CantBeDeletedException to 422 at the controller boundary
When it happens
Trigger: Calling module destroy with the id of a system/default module — one whose can_be_deleted flag is false — e.g. a module created by template seeding rather than by the user.
Common situations: Scripts or API clients iterating all modules and deleting each, or a frontend that renders the delete affordance for non-deletable modules.
Related errors
- Could not get address book data.
- No address book found
- $e->getMessage()
- The user does not belong to the vault's account.
- The password is not valid.
AI-assisted analysis of monicahq/monica@e08e917341 (2026-08-17).
Data as JSON: /api/errors/65ec85f108f67fd6.
Report an issue: GitHub.