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

  1. 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
  2. Delete the compiled cache (rm -rf cache/) so setup is rebuilt from the YAML sources
  3. Compare against the stock system/defines defaults to confirm streams.schemes is present after merge
  4. 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

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


AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17). Data as JSON: /api/errors/cfd988415e649154. Report an issue: GitHub.