{"id":"d3c3d6f041d9acd2","repo":"laravel/framework","slug":"scoped-disk-is-missing-prefix-configuration-opti","errorCode":null,"errorMessage":"Scoped disk is missing \"prefix\" configuration option.","messagePattern":"Scoped disk is missing \"prefix\" configuration option\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Filesystem/FilesystemManager.php","lineNumber":303,"sourceCode":"        }\n\n        return Arr::except($config, ['token']);\n    }\n\n    /**\n     * Create a scoped driver.\n     *\n     * @param  array  $config\n     * @return \\Illuminate\\Contracts\\Filesystem\\Filesystem\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function createScopedDriver(array $config)\n    {\n        if (empty($config['disk'])) {\n            throw new InvalidArgumentException('Scoped disk is missing \"disk\" configuration option.');\n        } elseif (empty($config['prefix'])) {\n            throw new InvalidArgumentException('Scoped disk is missing \"prefix\" configuration option.');\n        }\n\n        return $this->build(tap(\n            is_string($config['disk']) ? $this->getConfig($config['disk']) : $config['disk'],\n            function (&$parent) use ($config) {\n                if (empty($parent['prefix'])) {\n                    $parent['prefix'] = $config['prefix'];\n                } else {\n                    $separator = $parent['directory_separator'] ?? DIRECTORY_SEPARATOR;\n\n                    $parentPrefix = rtrim($parent['prefix'], $separator);\n                    $scopedPrefix = ltrim($config['prefix'], $separator);\n\n                    $parent['prefix'] = \"{$parentPrefix}{$separator}{$scopedPrefix}\";\n                }\n\n                if (isset($config['visibility'])) {\n                    $parent['visibility'] = $config['visibility'];","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Filesystem/FilesystemManager.php#L285-L321","documentation":"Thrown by FilesystemManager::createScopedDriver() when a 'scoped' disk config omits the 'prefix' key. The prefix is the path segment prepended to every operation on the parent disk; without it the scope would be a no-op and the disk would behave identically to its parent.","triggerScenarios":"Defining a scoped disk with 'driver' => 'scoped' and 'disk' but no 'prefix', then resolving that disk.","commonSituations":"Building scoped/tenant disks and forgetting the prefix; refactoring config and dropping the line; using 'path' instead of 'prefix'.","solutions":["Add a 'prefix' key, e.g. 'prefix' => 'tenant-a'.","Confirm prefix has no leading/trailing separators that would double-slash paths.","Remember scoped disks require both 'disk' and 'prefix'."],"exampleFix":"// before\n// 'disks' => ['tenants' => ['driver' => 'scoped', 'disk' => 's3']]\n\n// after\n// 'disks' => ['tenants' => ['driver' => 'scoped', 'disk' => 's3', 'prefix' => 'tenant-a']]","handlingStrategy":"validation","validationCode":"$cfg = config(\"filesystems.disks.{$name}\");\nif (($cfg['driver'] ?? null) === 'scoped' && empty($cfg['prefix'])) {\n    throw new RuntimeException('Scoped disk requires a \"prefix\" option');\n}","typeGuard":"function scopedDiskHasPrefix(array $config): bool\n{\n    return ($config['driver'] ?? '') === 'scoped' && !empty($config['prefix']);\n}","tryCatchPattern":"try {\n    return Storage::disk($name);\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'missing \"prefix\"')) {\n        abort(500, 'Scoped disk misconfigured: missing prefix');\n    }\n    throw $e;\n}","preventionTips":["Always set 'prefix' on scoped disks.","Avoid leading/trailing separators in prefix values.","Validate scoped disk config at deploy time."],"tags":["filesystem","configuration","scoped-disk","prefix","multi-tenant"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}