UnconfiguredFilesystemDisk
Emitted when Storage::disk() / Storage::drive() (or the same call on the root \Storage alias) is given a disk name that is not a key in filesystems.disks. String literals, string-backed enum cases (Storage::disk(Disk::Archive)), and class constants typed as one string literal (self::DISK included) are checked.
Why this is a problem
An unconfigured disk name is not a silent fallback to the local disk. FilesystemManager::resolve() throws a hard InvalidArgumentException at runtime, so the failure mode is availability (the request or job dies), not a wrong write target.
Examples
// filesystems.disks configures: local, public, s3
// Bad: no 's3-old' disk configured
Storage::disk('s3-old')->put('file.txt', $contents); // UnconfiguredFilesystemDisk
// A close match is suggested:
// "Disk 'publik' is not configured in filesystems.disks, did you mean 'public'?"
Storage::disk('publik')->put('file.txt', $contents);
// Good
Storage::disk('s3')->put('file.txt', $contents);
How to fix
- Check the disk name against
config/filesystems.php’sdisksarray - Fix the typo, or add the missing disk to
filesystems.disks
Configuration
This check is enabled by default. Reported at error levels 1 to 4 (like Psalm’s UndefinedMagicMethod), info at looser levels. Disable it in your psalm.xml:
<plugins>
<pluginClass class="Psalm\LaravelPlugin\Plugin">
<findUnconfiguredFilesystemDisks value="false" />
</pluginClass>
</plugins>
Limitations
- Only calls through the
Storagefacade (and its root\Storagealias, when the app registers it inconfig('app.aliases')) are checked. A DI-injectedFilesystemManager(orFactorycontract) receiver is skipped, since it may be a userland subclass with its own disk resolution (an overriddengetConfig(), for example) - Int-backed and pure enum cases,
static::/parent::constants, global constants, concatenation, variables, andnullare skipped - Falsy names (
Storage::disk(''),Storage::disk('0')) are skipped. Laravel resolves them to the default disk, not a lookup failure - Dotted names (
Storage::disk('tenant.assets')) are skipped. Laravel resolves them through its dotted config lookup into nesteddisksgroups, and the check only knows top-level keys - Disabled when the project is analyzed under the Testbench package-mode fallback (no
bootstrap/app.phpresolved), since that boot reads Testbench’s own bundled config, not the analyzed project’s. Also disabled when the boot recorded a bootstrap error, since a partially booted app may be missing disks that providers would have merged - A disk registered at runtime is not visible to this check and is reported anyway.
Storage::fake('avatars')andFilesystemManager::set($name, $disk)write into$disks[$name], whichFilesystemManager::get()reads before falling through toresolve(). SoStorage::fake('avatars'); Storage::disk('avatars');in a test reports even though the code is correct. Add the disk toconfig/filesystems.disks, or suppress the issue in that file