{"record":{"id":"cfd988415e649154","repo":"getgrav/grav","slug":"configuration-is-missing-streams-schemes","errorCode":null,"errorMessage":"Configuration is missing streams.schemes!","messagePattern":"Configuration is missing streams\\.schemes!","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"critical","filePath":"system/src/Grav/Common/Config/Setup.php","lineNumber":394,"sourceCode":"\n            $schemes[$scheme] = $type;\n        }\n\n        return $schemes;\n    }\n\n    /**\n     * @param UniformResourceLocator $locator\n     * @return void\n     * @throws InvalidArgumentException\n     * @throws BadMethodCallException\n     * @throws RuntimeException\n     */\n    protected function check(UniformResourceLocator $locator)\n    {\n        $streams = $this->items['streams']['schemes'] ?? null;\n        if (!is_array($streams)) {\n            throw new InvalidArgumentException('Configuration is missing streams.schemes!');\n        }\n        $diff = array_keys(array_diff_key($this->streams, $streams));\n        if ($diff) {\n            throw new InvalidArgumentException(\n                sprintf('Configuration is missing keys %s from streams.schemes!', implode(', ', $diff))\n            );\n        }\n\n        try {\n            // Strip missing override locations from environment://. Runs even when the env\n            // dir itself does not exist on disk, otherwise the stale prefix lingers and a\n            // later write (e.g. config save under a hostname variant) materializes the dir.\n            $force = $this->get('streams.schemes.environment.force', false);\n            if (!$force) {\n                $prefixes = $this->get('streams.schemes.environment.prefixes.');\n                $update = false;\n                foreach ($prefixes as $i => $prefix) {\n                    if ($locator->isStream($prefix)) {","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/getgrav/grav/blob/6040efed04efa69b8209448ed81308e7c24147c2/system/src/Grav/Common/Config/Setup.php#L376-L412","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# user/config/system.yaml — before\nstreams: []   # wipes the scheme map\n\n# after — remove the key entirely; Grav supplies the defaults\n# (delete the line)","handlingStrategy":"validation","validationCode":"// deploy-time check: merged setup must keep a scheme map\n$setupItems = $setup->toArray(); // or parse the yaml sources\nif (!is_array($setupItems['streams']['schemes'] ?? null)) {\n    throw new RuntimeException('streams.schemes missing — user config clobbered the defaults');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $grav['config']; // triggers setup/check()\n} catch (InvalidArgumentException $e) {\n    // boot-stopping config error: surface a 503 and page ops rather than a fatal trace\n}","preventionTips":["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"],"tags":["grav","configuration","streams","bootstrap","invalid-argument"],"backgroundTag":"missing-config-key","analyzedSha":"6040efed04efa69b8209448ed81308e7c24147c2","analyzedAt":"2026-08-17T05:07:31.593Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}