{"record":{"id":"fc6744314eb1b69d","repo":"mongodb/laravel-mongodb","slug":"read-only-adapter-for-flysystem-is-missing-try-running","errorCode":null,"errorMessage":"Read-only Adapter for Flysystem is missing. Try running \"composer require league/flysystem-read-only\"","messagePattern":"Read-only Adapter for Flysystem is missing\\. Try running \"composer require league/flysystem-read-only\"","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/MongoDBServiceProvider.php","lineNumber":153,"sourceCode":"                    if (! $connection instanceof Connection) {\n                        throw new InvalidArgumentException(sprintf('The database connection \"%s\" does not use the \"mongodb\" driver.', $config['connection'] ?? $app['config']['database.default']));\n                    }\n\n                    $bucket = $connection->getClient()\n                        ->getDatabase($config['database'] ?? $connection->getDatabaseName())\n                        ->selectGridFSBucket(['bucketName' => $config['bucket'] ?? 'fs', 'disableMD5' => true]);\n                }\n\n                if (! $bucket instanceof Bucket) {\n                    throw new InvalidArgumentException(sprintf('Unexpected value for GridFS \"bucket\" configuration. Expecting \"%s\". Got \"%s\"', Bucket::class, get_debug_type($bucket)));\n                }\n\n                $adapter = new GridFSAdapter($bucket, $config['prefix'] ?? '');\n\n                /** @see FilesystemManager::createFlysystem() */\n                if ($config['read-only'] ?? false) {\n                    if (! class_exists(ReadOnlyFilesystemAdapter::class)) {\n                        throw new RuntimeException('Read-only Adapter for Flysystem is missing. Try running \"composer require league/flysystem-read-only\"');\n                    }\n\n                    $adapter = new ReadOnlyFilesystemAdapter($adapter);\n                }\n\n                /** Prevent using backslash on Windows in {@see FilesystemAdapter::__construct()} */\n                $config['directory_separator'] = '/';\n\n                return new FilesystemAdapter(new Filesystem($adapter, $config), $adapter, $config);\n            });\n        });\n    }\n\n    private function registerBoostTools(): void\n    {\n        if (! class_exists(BoostServiceProvider::class)) {\n            return;\n        }","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/mongodb/laravel-mongodb/blob/0634653039468ceb0268a69192bdac64469ed043/src/MongoDBServiceProvider.php#L135-L171","documentation":"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.","triggerScenarios":"Setting 'read-only' => true on a gridfs filesystem disk without league/flysystem-read-only being present in vendor (class_exists check fails).","commonSituations":"Deploying to a production environment where dev dependencies differ, or adding the read-only flag to config without running composer update/require.","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."],"exampleFix":"// before\ncomposer install  # flysystem-read-only missing\n// after\ncomposer require league/flysystem-read-only","handlingStrategy":"validation","validationCode":"if (config('filesystems.disks.gridfs.read-only') && ! class_exists(League\\Flysystem\\ReadOnly\\ReadOnlyFilesystemAdapter::class)) {\n    throw new RuntimeException('Run composer require league/flysystem-read-only');\n}","typeGuard":"function readOnlyAdapterAvailable(): bool { return class_exists(League\\Flysystem\\ReadOnly\\ReadOnlyFilesystemAdapter::class); }","tryCatchPattern":"try {\n    Storage::disk('gridfs-readonly')->files();\n} catch (RuntimeException $e) {\n    if (str_contains($e->getMessage(), 'flysystem-read-only')) {\n        abort(500, 'Server missing league/flysystem-read-only; run composer require.');\n    }\n    throw $e;\n}","preventionTips":["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"],"tags":["flysystem","composer","missing-package"],"backgroundTag":"missing-optional-dependency","analyzedSha":"0634653039468ceb0268a69192bdac64469ed043","analyzedAt":"2026-09-15T02:56:37.067Z","contentChangedAt":"2026-09-15T02:56:37.067Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}