mongodb/laravel-mongodb · error · RuntimeException
Read-only Adapter for Flysystem is missing. Try running…
Error message
Read-only Adapter for Flysystem is missing. Try running "composer require league/flysystem-read-only"
What it means
When a GridFS flysystem disk is configured as read-only, the package wraps the adapter in league/flysystem-read-only's ReadOnlyFilesystemAdapter. If that package is not installed, the RuntimeException is thrown telling you exactly which composer package to add.
Solutions
- Run: composer require league/flysystem-read-only
- If the read-only flag is not needed, remove 'read-only' => true from the disk config.
- Verify vendor/league/flysystem-read-only exists after deployment; ensure the package is in require (not require-dev) if used in production.
Example fix
// before composer install # flysystem-read-only missing // after composer require league/flysystem-read-only
Defensive patterns
Strategy: validation
Validate before calling
if (config('filesystems.disks.gridfs.read-only') && ! class_exists(League\Flysystem\ReadOnly\ReadOnlyFilesystemAdapter::class)) {
throw new RuntimeException('Run composer require league/flysystem-read-only');
} Type guard
function readOnlyAdapterAvailable(): bool { return class_exists(League\Flysystem\ReadOnly\ReadOnlyFilesystemAdapter::class); } Try / catch
try {
Storage::disk('gridfs-readonly')->files();
} catch (RuntimeException $e) {
if (str_contains($e->getMessage(), 'flysystem-read-only')) {
abort(500, 'Server missing league/flysystem-read-only; run composer require.');
}
throw $e;
} Prevention
- Put league/flysystem-read-only in the main require section, not require-dev
- Run composer install in CI to catch missing packages before deploy
- Verify installed packages with composer show league/flysystem-read-only
- Only set read-only: true if the package is part of your standard build
When it happens
Trigger: Setting 'read-only' => true on a gridfs filesystem disk without league/flysystem-read-only being present in vendor (class_exists check fails).
Common situations: Deploying to a production environment where dev dependencies differ, or adding the read-only flag to config without running composer update/require.
Understand the failure class
Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.
Related errors
- Unexpected value for GridFS "bucket" configuration…
- Aggregation builder requires package mongodb/builder 0.2+
AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15).
Data as JSON: /api/errors/fc6744314eb1b69d.
Report an issue: GitHub.
Appendix: source
Thrown at src/MongoDBServiceProvider.php:153
if (! $connection instanceof Connection) {
throw new InvalidArgumentException(sprintf('The database connection "%s" does not use the "mongodb" driver.', $config['connection'] ?? $app['config']['database.default']));
}
$bucket = $connection->getClient()
->getDatabase($config['database'] ?? $connection->getDatabaseName())
->selectGridFSBucket(['bucketName' => $config['bucket'] ?? 'fs', 'disableMD5' => true]);
}
if (! $bucket instanceof Bucket) {
throw new InvalidArgumentException(sprintf('Unexpected value for GridFS "bucket" configuration. Expecting "%s". Got "%s"', Bucket::class, get_debug_type($bucket)));
}
$adapter = new GridFSAdapter($bucket, $config['prefix'] ?? '');
/** @see FilesystemManager::createFlysystem() */
if ($config['read-only'] ?? false) {
if (! class_exists(ReadOnlyFilesystemAdapter::class)) {
throw new RuntimeException('Read-only Adapter for Flysystem is missing. Try running "composer require league/flysystem-read-only"');
}
$adapter = new ReadOnlyFilesystemAdapter($adapter);
}
/** Prevent using backslash on Windows in {@see FilesystemAdapter::__construct()} */
$config['directory_separator'] = '/';
return new FilesystemAdapter(new Filesystem($adapter, $config), $adapter, $config);
});
});
}
private function registerBoostTools(): void
{
if (! class_exists(BoostServiceProvider::class)) {
return;
}View on GitHub (pinned to 0634653039)