getgrav/grav · critical · InvalidArgumentException
Configuration is missing streams.schemes!
Error message
Configuration is missing streams.schemes!
What it means
Near the end of boot, Setup::check() validates that the merged setup configuration still contains a streams.schemes array (the map of stream scheme definitions like user, cache, system). If items['streams']['schemes'] is absent or not an array, it throws InvalidArgumentException 'Configuration is missing streams.schemes!' — the stream subsystem has nothing to register, so Grav refuses to continue. It almost always means the streams key was clobbered or replaced by user-level configuration.
Source
Thrown at system/src/Grav/Common/Config/Setup.php:394
$schemes[$scheme] = $type;
}
return $schemes;
}
/**
* @param UniformResourceLocator $locator
* @return void
* @throws InvalidArgumentException
* @throws BadMethodCallException
* @throws RuntimeException
*/
protected function check(UniformResourceLocator $locator)
{
$streams = $this->items['streams']['schemes'] ?? null;
if (!is_array($streams)) {
throw new InvalidArgumentException('Configuration is missing streams.schemes!');
}
$diff = array_keys(array_diff_key($this->streams, $streams));
if ($diff) {
throw new InvalidArgumentException(
sprintf('Configuration is missing keys %s from streams.schemes!', implode(', ', $diff))
);
}
try {
// Strip missing override locations from environment://. Runs even when the env
// dir itself does not exist on disk, otherwise the stale prefix lingers and a
// later write (e.g. config save under a hostname variant) materializes the dir.
$force = $this->get('streams.schemes.environment.force', false);
if (!$force) {
$prefixes = $this->get('streams.schemes.environment.prefixes.');
$update = false;
foreach ($prefixes as $i => $prefix) {
if ($locator->isStream($prefix)) {View on GitHub (pinned to 6040efed04)
Solutions
- Check user/config/system.yaml (and any environment override) for a streams key that is null, empty, or malformed, and remove it so defaults apply
- Delete the compiled cache (rm -rf cache/) so setup is rebuilt from the YAML sources
- Compare against the stock system/defines defaults to confirm streams.schemes is present after merge
- If a plugin manipulates setup config, disable it and re-test boot
Example fix
# user/config/system.yaml — before streams: [] # wipes the scheme map # after — remove the key entirely; Grav supplies the defaults # (delete the line)
Defensive patterns
Strategy: validation
Validate before calling
// deploy-time check: merged setup must keep a scheme map
$setupItems = $setup->toArray(); // or parse the yaml sources
if (!is_array($setupItems['streams']['schemes'] ?? null)) {
throw new RuntimeException('streams.schemes missing — user config clobbered the defaults');
} Try / catch
try {
$grav['config']; // triggers setup/check()
} catch (InvalidArgumentException $e) {
// boot-stopping config error: surface a 503 and page ops rather than a fatal trace
} Prevention
- Never set streams: to null/[] in system.yaml — remove the key to inherit defaults
- Validate config files in CI (yaml lint + key presence for streams.schemes) before deploy
- After upgrades, diff your system.yaml against the new stock one to catch renamed/required blocks
When it happens
Trigger: user/config/system.yaml (or a streams.yaml merged into setup) setting streams: null, streams: [] or replacing streams.schemes wholesale with a non-array; a corrupted compiled setup cache serving a mangled structure; a plugin writing invalid data into the setup config during onFatalException-level early events.
Common situations: Hand-editing system.yaml and accidentally removing/blanking the streams block; copying a partial system.yaml over the site's during an upgrade; multi-environment config where user/env/<host>/config/system.yaml lacks the required keys; stale compiled cache after the config files changed underneath it.
Related errors
- Setup: Configuration reload loop detected!
- Configuration is missing keys %s from streams.schemes!
- No backups defined...
- Backup location: {$backup_root} does not exist...
- Cache folder not defined.
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/cfd988415e649154.
Report an issue: GitHub.