{"record":{"id":"128589153a184faa","repo":"getgrav/grav","slug":"flash-has-no-directory","errorCode":null,"errorMessage":"Flash has no directory","messagePattern":"Flash has no directory","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"system/src/Grav/Framework/Flex/FlexDirectoryForm.php","lineNumber":128,"sourceCode":"     * @return $this\n     */\n    public function initialize()\n    {\n        $this->messages = [];\n        $this->submitted = false;\n        $this->data =  new Data($this->directory->loadDirectoryConfig($this->name), $this->getBlueprint());\n        $this->files = [];\n        $this->unsetFlash();\n\n        /** @var FlexFormFlash $flash */\n        $flash = $this->getFlash();\n        if ($flash->exists()) {\n            $data = $flash->getData();\n            $includeOriginal = (bool)($this->getBlueprint()->form()['images']['original'] ?? null);\n\n            $directory = $flash->getDirectory();\n            if (null === $directory) {\n                throw new RuntimeException('Flash has no directory');\n            }\n            $this->directory = $directory;\n            $this->data = $data ? new Data($data, $this->getBlueprint()) : null;\n            $this->files = $flash->getFilesByFields($includeOriginal);\n        }\n\n        return $this;\n    }\n\n    /**\n     * @param string $uniqueId\n     * @return void\n     */\n    public function setUniqueId(string $uniqueId): void\n    {\n        if ($uniqueId !== '') {\n            $this->uniqueid = $uniqueId;\n        }","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/getgrav/grav/blob/6040efed04efa69b8209448ed81308e7c24147c2/system/src/Grav/Framework/Flex/FlexDirectoryForm.php#L110-L146","documentation":"During FlexDirectoryForm initialization the form loads its FlexFormFlash (per-session upload/form state) and requires a directory from it. FlexFormFlash::init() restores the directory either from the stored flash JSON ('object.type' or 'directory.type' resolved through the Flex registry) or from config; if both fail, getDirectory() returns null and this RuntimeException is thrown. In practice the flash exists in the session but its flex context cannot be reconstructed.","triggerScenarios":"A flex type was renamed/removed between the request that created the flash and the request that renders the form (deploy while users had forms open); the flex directory is not registered in Grav's Flex object (missing blueprints/flex configuration); a stale session flash file created by another form id collision; session data persisted across a major Grav upgrade with an older flash schema.","commonSituations":"Deploying a plugin whose flex collection type changed name while admin users kept logged-in sessions; dev environment with long-lived sessions across code changes; flash files under user/data forming leftovers after uninstalling a flex plugin.","solutions":["Clear the stale flash: delete the form flash files (user/data/form-flash or via FormFlash::delete()) or log out/in to reset the session.","Verify the flex type is still registered: $flex->getDirectory('type') must return a FlexDirectory in the new code.","Pass 'directory' in the form/flash options when constructing the form so initialization does not depend on stored state.","After renames, keep a back-compat alias for the old flex type or ask affected users to restart the form."],"exampleFix":"// before\n$form = FlexDirectoryForm::instance(['directory' => $directory, 'name' => 'config']);\n$form->initialize(); // Flash has no directory (stale session flash)\n\n// after\n$flash = new FlexFormFlash($form->getFlash()->getUniqueId());\n$flash->delete(); // discard stale flash, then re-init\n$form = FlexDirectoryForm::instance(['directory' => $directory, 'name' => 'config']);","handlingStrategy":"validation","validationCode":"// Ensure a clean flash before initializing a directory form\n$flash = new \\Grav\\Framework\\Flex\\FlexFormFlash($uniqueId);\nif ($flash->exists() && $flash->getDirectory() === null) {\n    $flash->delete(); // stale/unresolvable flash: restart the form\n}\n$form = FlexDirectoryForm::instance(['directory' => $directory, 'name' => $name])->initialize();","typeGuard":null,"tryCatchPattern":"try {\n    $form->initialize();\n} catch (\\Grav\\Framework\\Flex\\Exception\\RuntimeException $e) {\n    if (str_contains($e->getMessage(), 'Flash has no directory')) {\n        $form->getFlash()->delete(); // clear state, re-init on next request\n    }\n}","preventionTips":["Pass 'directory' explicitly when constructing directory forms so flash init has a fallback.","Keep flex type names stable across releases, or register compatibility aliases after renames.","Purge user/data form-flash leftovers when uninstalling or renaming flex plugins.","Bump form unique ids on major Grav upgrades."],"tags":["grav","flex","forms","flash","session-state"],"backgroundTag":"stale-session-state","analyzedSha":"6040efed04efa69b8209448ed81308e7c24147c2","analyzedAt":"2026-08-17T05:07:31.593Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}