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

  1. Delete only user-created modules; check the can_be_deleted flag first
  2. Filter the UI/command to hide or skip modules with can_be_deleted = false
  3. 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

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


AI-assisted analysis of monicahq/monica@e08e917341 (2026-08-17). Data as JSON: /api/errors/65ec85f108f67fd6. Report an issue: GitHub.