getgrav/grav · error · InvalidArgumentException

Stream '{$type}' could not be initialized.

Error message

Stream '{$type}' could not be initialized.

What it means

During Themes::configure(), every scheme declared in the theme's streams.schemes config (plus the implicit theme scheme) is registered as a PHP stream wrapper after unregistering any existing wrapper with that name. If stream_wrapper_register($scheme, $type) returns false, Grav throws this InvalidArgumentException. $type is resolved to \RocketTheme\Toolbox\StreamWrapper\<type> unless it starts with a backslash, so both an invalid scheme name and a nonexistent wrapper class land here (PHP emits a warning and returns false when the class does not exist).

Source

Thrown at system/src/Grav/Common/Themes.php:353

            if (isset($config['paths'])) {
                $locator->addPath($scheme, '', $config['paths']);
            }
            if (isset($config['prefixes'])) {
                foreach ($config['prefixes'] as $prefix => $paths) {
                    $locator->addPath($scheme, $prefix, $paths);
                }
            }

            if (in_array($scheme, $registered, true)) {
                stream_wrapper_unregister($scheme);
            }
            $type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream';
            if ($type[0] !== '\\') {
                $type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type;
            }

            if (!stream_wrapper_register($scheme, $type)) {
                throw new InvalidArgumentException("Stream '{$type}' could not be initialized.");
            }
        }

        // Load languages after streams has been properly initialized
        $this->loadLanguages($this->config);
    }

    /**
     * Load theme configuration.
     *
     * @param string $name   Theme name
     * @param Config $config Configuration class
     * @return void
     */
    protected function loadConfiguration($name, Config $config)
    {
        $themeConfig = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT)->content();
        $config->joinDefaults("themes.{$name}", $themeConfig);

View on GitHub (pinned to 6040efed04)

Solutions

  1. Fix the type value in user/themes/<name>/<name>.yaml: use ReadOnlyStream (the default), another class in RocketTheme\Toolbox\StreamWrapper, or a leading-backslash FQCN that is already loaded
  2. For custom wrappers, ensure the class exists and is autoloaded before theme init (composer autoload of the theme/plugin providing it)
  3. Keep scheme names simple identifiers (letters, digits, dots, dashes) with no '://' or slashes
  4. Run bin/grav clearcache after fixing so the cached configuration is rebuilt

Example fix

# before (user/themes/mytheme/mytheme.yaml)
streams:
  schemes:
    media:
      type: ReadableStream   # class does not exist

# after
streams:
  schemes:
    media:
      type: ReadOnlyStream
Defensive patterns

Strategy: validation

Validate before calling

// validate custom stream config before Grav registers it
$class = str_starts_with($type, '\\') ? $type : '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type;
if (!preg_match('/^[a-zA-Z][a-zA-Z0-9.+-]*$/', $scheme) || !class_exists($class)) {
    throw new InvalidArgumentException("Bad stream scheme '{$scheme}' or type '{$type}' — fix theme streams config");
}

Try / catch

try { $themes->configure(); } catch (InvalidArgumentException $e) { // fall back to default stream config and log
    $grav['debugger']->addException($e); }

Prevention

When it happens

Trigger: A theme's YAML declares streams.schemes.<scheme>.type with a typo (e.g. ReadableStream instead of ReadOnlyStream); a fully-qualified custom type: \My\Wrapper whose class is not autoloadable at theme-init time; an invalid scheme name containing ':' or '/' or an empty name; the wrapper class living in a plugin that loads after themes.

Common situations: Hand-editing theme YAML to add custom streams; copying stream configuration from a plugin without its autoloader; upgrading rockettheme/toolbox where wrapper classes changed; characters copied from docs into scheme names.

Related errors


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