getgrav/grav · error · RuntimeException

__METHOD__(): 'object' should be instance of FlexObjectInter

Error message

__METHOD__(): 'object' should be instance of FlexObjectInterface

What it means

FlexForm::instance() accepts an 'object' option that must implement FlexObjectInterface; anything else (a plain object, an array, a legacy Page) triggers this 400 RuntimeException. The factory delegates form creation to the object itself, so it must be a real Flex object. Use the 'directory'+'key' path instead when you do not have an object instance.

Source

Thrown at system/src/Grav/Framework/Flex/FlexForm.php:76

    private $submitMethod;

    /**
     * @param array $options    Options to initialize the form instance:
     *                          (string) name: Form name, allows you to use custom form.
     *                          (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);

View on GitHub (pinned to 6040efed04)

Solutions

  1. Load a proper Flex object first: $object = $grav['flex']->getDirectory('pages')->getObject($key); then pass it.
  2. If you only know type+key, use FlexForm::instance(['directory' => $directory, 'key' => $key]) instead of 'object'.
  3. For legacy Page instances, migrate to the Flex page object via the pages flex directory before building the form.

Example fix

// before
$form = FlexForm::instance(['object' => $page]); // $page is legacy PageInterface

// after
$flex = Grav::instance()['flex'];
$object = $flex->getDirectory('pages')->getObject($page->route());
$form = FlexForm::instance(['object' => $object]);
Defensive patterns

Strategy: type-guard

Type guard

use Grav\Framework\Flex\Interfaces\FlexObjectInterface;

function isFlexObject(mixed $value): bool
{
    return $value instanceof FlexObjectInterface;
}

Prevention

When it happens

Trigger: Passing a legacy Grav Page (PageInterface) or stdClass/array where a FlexObject is expected; passing an object from a different abstraction layer (e.g. a Doctrine entity); passing an uninitialized FlexObjectInterface mock in tests.

Common situations: Porting legacy page code to Flex Pages and reusing $page variables in FlexForm::instance(); plugin code receiving 'object' from a request/JSON payload instead of loading it from the directory.

Related errors


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