getgrav/grav · error · RuntimeException
__METHOD__(): You need to pass option 'directory' or 'object
Error message
__METHOD__(): You need to pass option 'directory' or 'object'
What it means
FlexForm::instance() throws this 400 RuntimeException when the options array contains neither 'object' nor 'directory'. The factory has no way to know which flex type the form belongs to, so building the form is impossible. It is a strict usage contract: exactly one of the two options must be present.
Source
Thrown at system/src/Grav/Framework/Flex/FlexForm.php:86
*
* @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 $name
* @param FlexObjectInterface $object
* @param array|null $options
*/
public function __construct(string $name, FlexObjectInterface $object, ?array $options = null)
{View on GitHub (pinned to 6040efed04)
Solutions
- Default the call to a directory: $form = FlexForm::instance(['directory' => $flex->getDirectory($type), 'key' => $key, 'name' => $name]);
- If the object may exist, branch: $object ? ['object' => $object] : ['directory' => $directory, 'key' => $key].
- Assert before calling that isset($options['object']) || isset($options['directory']) so misconfiguration fails with a clearer message.
Example fix
// before
$options = ['name' => 'edit'];
$form = FlexForm::instance($options);
// after
$options += $object
? ['object' => $object]
: ['directory' => $directory, 'key' => $key];
$form = FlexForm::instance($options); Defensive patterns
Strategy: validation
Validate before calling
// Assert the factory contract before calling instance()
if (!isset($options['object']) && !isset($options['directory'])) {
throw new \InvalidArgumentException('FlexForm::instance() requires option object or directory.');
}
$form = FlexForm::instance($options); Prevention
- Build option arrays with an unconditional fallback: $options += ['directory' => $directory, 'key' => $key];
- Log the resolved options before the call in dev environments to catch dynamic-building bugs.
- Cover form factory calls with unit tests exercising both the object and directory paths.
When it happens
Trigger: FlexForm::instance(['name' => 'custom']) with only metadata options; empty options array; code paths where the options array is built dynamically and both keys were conditionally skipped (e.g. no object found and directory lookup returned null).
Common situations: Dynamic form factories in plugins where the object/directory is fetched conditionally and can end up unset; refactoring that moved the option setting but left the instance() call; copy-pasted skeleton code missing the required option.
Related errors
- __METHOD__(): You need to pass option 'directory'
- Flash has no directory
- __METHOD__(): 'object' should be instance of FlexObjectInter
- __METHOD__(): 'directory' should be instance of FlexDirector
- Flash has no object
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/caf10cf53e200457.
Report an issue: GitHub.