{"record":{"id":"caf10cf53e200457","repo":"getgrav/grav","slug":"method-you-need-to-pass-option-directory-caf10c","errorCode":null,"errorMessage":"__METHOD__(): You need to pass option 'directory' or 'object'","messagePattern":"__METHOD__\\(\\): You need to pass option 'directory' or 'object'","errorType":"exception","errorClass":"RuntimeException","httpStatus":400,"severity":"error","filePath":"system/src/Grav/Framework/Flex/FlexForm.php","lineNumber":86,"sourceCode":"     *\n     * @return FlexFormInterface\n     */\n    public static function instance(array $options = [])\n    {\n        if (isset($options['object'])) {\n            $object = $options['object'];\n            if (!$object instanceof FlexObjectInterface) {\n                throw new RuntimeException(__METHOD__ . \"(): 'object' should be instance of FlexObjectInterface\", 400);\n            }\n        } elseif (isset($options['directory'])) {\n            $directory = $options['directory'];\n            if (!$directory instanceof FlexDirectory) {\n                throw new RuntimeException(__METHOD__ . \"(): 'directory' should be instance of FlexDirectory\", 400);\n            }\n            $key = $options['key'] ?? '';\n            $object = $directory->getObject($key) ?? $directory->createObject([], $key);\n        } else {\n            throw new RuntimeException(__METHOD__ . \"(): You need to pass option 'directory' or 'object'\", 400);\n        }\n\n        $name = $options['name'] ?? '';\n\n        // There is no reason to pass object and directory.\n        unset($options['object'], $options['directory']);\n\n        return $object->getForm($name, $options);\n    }\n\n    /**\n     * FlexForm constructor.\n     * @param string $name\n     * @param FlexObjectInterface $object\n     * @param array|null $options\n     */\n    public function __construct(string $name, FlexObjectInterface $object, ?array $options = null)\n    {","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/getgrav/grav/blob/6040efed04efa69b8209448ed81308e7c24147c2/system/src/Grav/Framework/Flex/FlexForm.php#L68-L104","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\n$options = ['name' => 'edit'];\n$form = FlexForm::instance($options);\n\n// after\n$options += $object\n    ? ['object' => $object]\n    : ['directory' => $directory, 'key' => $key];\n$form = FlexForm::instance($options);","handlingStrategy":"validation","validationCode":"// Assert the factory contract before calling instance()\nif (!isset($options['object']) && !isset($options['directory'])) {\n    throw new \\InvalidArgumentException('FlexForm::instance() requires option object or directory.');\n}\n$form = FlexForm::instance($options);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["grav","flex","forms","missing-argument","factory"],"backgroundTag":"missing-required-parameter","analyzedSha":"6040efed04efa69b8209448ed81308e7c24147c2","analyzedAt":"2026-08-17T05:07:31.593Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}