getgrav/grav · error · RuntimeException
__METHOD__(): 'directory' should be instance of FlexDirector
Error message
__METHOD__(): 'directory' should be instance of FlexDirectory
What it means
In FlexForm::instance(), when no 'object' is given the 'directory' option must be a FlexDirectory instance; passing the flex type string, an array of options, or any other value throws this 400 RuntimeException. The directory is used to look up or create the object by key, so a raw string cannot work here.
Source
Thrown at system/src/Grav/Framework/Flex/FlexForm.php:81
* (string) unique_id: Unique id for this form instance.
* (array) form: Custom form fields.
* (FlexObjectInterface) object: Object instance.
* (string) key: Object key, used only if object instance isn't given.
* (FlexDirectory) directory: Flex Directory, mandatory if object isn't given.
*
* @return FlexFormInterface
*/
public static function instance(array $options = [])
{
if (isset($options['object'])) {
$object = $options['object'];
if (!$object instanceof FlexObjectInterface) {
throw new RuntimeException(__METHOD__ . "(): 'object' should be instance of FlexObjectInterface", 400);
}
} elseif (isset($options['directory'])) {
$directory = $options['directory'];
if (!$directory instanceof FlexDirectory) {
throw new RuntimeException(__METHOD__ . "(): 'directory' should be instance of FlexDirectory", 400);
}
$key = $options['key'] ?? '';
$object = $directory->getObject($key) ?? $directory->createObject([], $key);
} else {
throw new RuntimeException(__METHOD__ . "(): You need to pass option 'directory' or 'object'", 400);
}
$name = $options['name'] ?? '';
// There is no reason to pass object and directory.
unset($options['object'], $options['directory']);
return $object->getForm($name, $options);
}
/**
* FlexForm constructor.
* @param string $nameView on GitHub (pinned to 6040efed04)
Solutions
- Resolve the string to a FlexDirectory first: $directory = $grav['flex']->getDirectory('pages'); then pass ['directory' => $directory, 'key' => $key].
- Check getDirectory() did not return null for unregistered types before calling instance().
- If you already have the object, pass 'object' instead and drop 'directory'.
Example fix
// before
$form = FlexForm::instance(['directory' => 'pages', 'key' => '/about']);
// after
$flex = Grav::instance()['flex'];
$form = FlexForm::instance([
'directory' => $flex->getDirectory('pages'),
'key' => '/about',
]); Defensive patterns
Strategy: type-guard
Type guard
use Grav\Framework\Flex\FlexDirectory;
function isFlexDirectory(mixed $value): bool
{
return $value instanceof FlexDirectory;
} Prevention
- Centralize directory resolution: $directory = $grav['flex']->getDirectory($type); assert non-null.
- Never pass type strings or config arrays as the 'directory' option.
- Add instanceof assertions at plugin boundaries that receive form options from external code.
When it happens
Trigger: FlexForm::instance(['directory' => 'pages', 'key' => '/blog']) passing the type name; passing a blueprint array or directory configuration array; passing a FlexIndex or collection object instead of the directory.
Common situations: First-time flex form integrations where authors assume the type string is accepted; refactoring from $grav['flex']->getDirectory() inline calls to options arrays and forgetting the resolution step.
Related errors
- __METHOD__(): 'object' should be instance of FlexObjectInter
- __METHOD__(): You need to pass option 'directory'
- Flash has no directory
- __METHOD__(): You need to pass option 'directory' or 'object
- Flash has no object
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/eb4545c397f266f5.
Report an issue: GitHub.