laravel/framework · error · InvalidArgumentException

Scoped disk is missing "prefix" configuration option.

Error message

Scoped disk is missing "prefix" configuration option.

What it means

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.

Source

Thrown at src/Illuminate/Filesystem/FilesystemManager.php:303

        }

        return Arr::except($config, ['token']);
    }

    /**
     * Create a scoped driver.
     *
     * @param  array  $config
     * @return \Illuminate\Contracts\Filesystem\Filesystem
     *
     * @throws \InvalidArgumentException
     */
    public function createScopedDriver(array $config)
    {
        if (empty($config['disk'])) {
            throw new InvalidArgumentException('Scoped disk is missing "disk" configuration option.');
        } elseif (empty($config['prefix'])) {
            throw new InvalidArgumentException('Scoped disk is missing "prefix" configuration option.');
        }

        return $this->build(tap(
            is_string($config['disk']) ? $this->getConfig($config['disk']) : $config['disk'],
            function (&$parent) use ($config) {
                if (empty($parent['prefix'])) {
                    $parent['prefix'] = $config['prefix'];
                } else {
                    $separator = $parent['directory_separator'] ?? DIRECTORY_SEPARATOR;

                    $parentPrefix = rtrim($parent['prefix'], $separator);
                    $scopedPrefix = ltrim($config['prefix'], $separator);

                    $parent['prefix'] = "{$parentPrefix}{$separator}{$scopedPrefix}";
                }

                if (isset($config['visibility'])) {
                    $parent['visibility'] = $config['visibility'];

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Add a 'prefix' key, e.g. 'prefix' => 'tenant-a'.
  2. Confirm prefix has no leading/trailing separators that would double-slash paths.
  3. Remember scoped disks require both 'disk' and 'prefix'.

Example fix

// before
// 'disks' => ['tenants' => ['driver' => 'scoped', 'disk' => 's3']]

// after
// 'disks' => ['tenants' => ['driver' => 'scoped', 'disk' => 's3', 'prefix' => 'tenant-a']]
Defensive patterns

Strategy: validation

Validate before calling

$cfg = config("filesystems.disks.{$name}");
if (($cfg['driver'] ?? null) === 'scoped' && empty($cfg['prefix'])) {
    throw new RuntimeException('Scoped disk requires a "prefix" option');
}

Type guard

function scopedDiskHasPrefix(array $config): bool
{
    return ($config['driver'] ?? '') === 'scoped' && !empty($config['prefix']);
}

Try / catch

try {
    return Storage::disk($name);
} catch (\InvalidArgumentException $e) {
    if (str_contains($e->getMessage(), 'missing "prefix"')) {
        abort(500, 'Scoped disk misconfigured: missing prefix');
    }
    throw $e;
}

Prevention

When it happens

Trigger: Defining a scoped disk with 'driver' => 'scoped' and 'disk' but no 'prefix', then resolving that disk.

Common situations: Building scoped/tenant disks and forgetting the prefix; refactoring config and dropping the line; using 'path' instead of 'prefix'.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/d3c3d6f041d9acd2.json. Report an issue: GitHub.