nextcloud/server · error · OCSException
could not remove app
Error message
could not remove app
What it means
OCSException (HTTP 500) thrown by ApiController::uninstallApp when installer->removeApp($appId) returns false (not when it throws). The controller first disables the app if enabled, then removes files and clears caches; a boolean false from removeApp means the app could not be uninstalled and the response carries no chained exception.
Source
Thrown at apps/appstore/lib/Controller/ApiController.php:241
* 200: App successfully uninstalled
*/
#[PasswordConfirmationRequired(strict: true)]
#[ApiRoute(verb: 'POST', url: '/api/v1/apps/uninstall')]
public function uninstallApp(string $appId): DataResponse {
$appId = $this->appManager->cleanAppId($appId);
if ($this->appManager->isEnabledForAnyone($appId)) {
$this->disableApp($appId);
}
$result = $this->installer->removeApp($appId);
if ($result !== false) {
// If this app was force enabled, remove the force-enabled-state
$this->appManager->removeOverwriteNextcloudRequirement($appId);
$this->appManager->clearAppsCache();
return new DataResponse([]);
}
throw new OCSException('could not remove app', Http::STATUS_INTERNAL_SERVER_ERROR);
}
/**
* Update an app
*
* @param string $appId - The app to update
* @return DataResponse<Http::STATUS_OK, array{}, array{}>
* @throws OCSException - if the app could not be updated
*
* 200: App successfully updated
*/
#[PasswordConfirmationRequired(strict: true)]
#[ApiRoute(verb: 'POST', url: '/api/v1/apps/update')]
public function updateApp(string $appId): DataResponse {
$appId = $this->appManager->cleanAppId($appId);
$this->config->setSystemValue('maintenance', true);
try {View on GitHub (pinned to ecdeb153ff)
Solutions
- Verify the app is third-party (installed under apps/ from the store) — shipped apps can only be disabled, not removed
- Check write/delete permission on the apps/ directory for the web server user
- Use `occ app:remove <appId>` to see whether the CLI path reports a clearer reason
- If the directory is gone but the DB still lists the app, clear caches / check oc_appconfig entries
Defensive patterns
Strategy: try-catch
Try / catch
try {
await axios.post(generateOcsUrl('/apps/appstore/apps/uninstall'), { appId })
} catch (e) {
// 500 'could not remove app' — removeApp returned false: not present on disk, perms, or a shipped app
} Prevention
- Offer uninstall only for third-party apps; shipped apps can merely be disabled
- Keep apps/ writable by the web server user so removal can delete files
- After failed uninstalls, verify on disk whether the app directory still exists before retrying
When it happens
Trigger: POST /ocs/appstore/apps/uninstall where removeApp returns false: app directory not present under apps/, files not deletable (permissions on apps/), or the app is shipped with the release and cannot be file-removed (only third-party apps are removable).
Common situations: Attempting to remove a bundled core app (only disable is possible); apps/ owned by root so the web server cannot delete the directory; app already deleted on disk but still registered in the database; leftover state from a previous failed install.
Related errors
- could not enable app
- could not disable app
- could not update app
- Bundle not found
- could not enable bundle
AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17).
Data as JSON: /api/errors/a9742720e4677b36.
Report an issue: GitHub.