getgrav/grav · error · RuntimeException
__METHOD__(): You need to pass option 'directory' or…
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.
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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- __METHOD__(): You need to pass option 'directory'
- Flash has no directory
- Flash has no object
- __METHOD__(): 'directory' should be instance of…
- __METHOD__(): 'object' should be instance of…
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/caf10cf53e200457.
Report an issue: GitHub.
Appendix: 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)