{"record":{"id":"de58e64fb9b4295d","repo":"getgrav/grav","slug":"cannot-unserialize-block-s","errorCode":null,"errorMessage":"Cannot unserialize Block: %s","messagePattern":"Cannot unserialize Block: (.+?)","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"system/src/Grav/Framework/ContentBlock/ContentBlock.php","lineNumber":77,"sourceCode":"     * @param array $serialized\n     * @return ContentBlockInterface\n     * @throws InvalidArgumentException\n     */\n    public static function fromArray(array $serialized)\n    {\n        try {\n            $type = $serialized['_type'] ?? null;\n            $id = $serialized['id'] ?? null;\n\n            if (!$type || !$id || !is_a($type, ContentBlockInterface::class, true)) {\n                throw new InvalidArgumentException('Bad data');\n            }\n\n            /** @var ContentBlockInterface $instance */\n            $instance = new $type($id);\n            $instance->build($serialized);\n        } catch (Exception $e) {\n            throw new InvalidArgumentException(sprintf('Cannot unserialize Block: %s', $e->getMessage()), $e->getCode(), $e);\n        }\n\n        return $instance;\n    }\n\n    /**\n     * Block constructor.\n     *\n     * @param string|null $id\n     */\n    public function __construct($id = null)\n    {\n        $this->id = $id ? (string) $id : $this->generateId();\n    }\n\n    /**\n     * @return string\n     */","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/getgrav/grav/blob/6040efed04efa69b8209448ed81308e7c24147c2/system/src/Grav/Framework/ContentBlock/ContentBlock.php#L59-L95","documentation":"Umbrella exception from ContentBlock::fromArray(): any Exception raised while reconstructing the block — the 'Bad data' guard, a failure inside `new $type($id)`, or anything thrown by $instance->build($serialized) (build() runs checkVersion() and recurses into self::fromArray() for every nested block) — is caught and re-thrown as this InvalidArgumentException with the original message interpolated via sprintf and the original exception chained as previous. Read $e->getPrevious() for the root cause.","triggerScenarios":"fromArray() on partially corrupted arrays; a '_version' mismatch bubbling up from build() as 'Unsupported version N'; a custom block class whose constructor or build() throws; deeply nested block trees where an inner block fails validation.","commonSituations":"Upgrading Grav with stale cached pages; cache/session backends returning truncated data; custom block implementations that throw during build(); data serialized by one Grav version replayed by another (dev cache imported into prod, rollback after upgrade).","solutions":["Inspect $e->getPrevious() — it carries the real cause ('Bad data', 'Unsupported version N', or a constructor/build error).","Clear the cache (bin/grav clear-cache) so blocks regenerate under the current version and class names.","Fix the referenced block class so that `new $type($id)` and build() cannot throw on well-formed data.","Catch this exception at the call site and regenerate the block from source content instead of surfacing the failure."],"exampleFix":"// before\n$block = ContentBlock::fromArray($cached);\n\n// after\ntry {\n    $block = ContentBlock::fromArray($cached);\n} catch (\\InvalidArgumentException $e) {\n    $log->warning('Block unserialize failed: ' . $e->getMessage(), ['previous' => $e->getPrevious()]);\n    $block = $page->buildContentBlock(); // regenerate from source\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $block = ContentBlock::fromArray($cached);\n} catch (\\InvalidArgumentException $e) {\n    // umbrella failure: inspect $e->getPrevious(), then regenerate\n    $log->warning($e->getMessage(), ['root' => $e->getPrevious()]);\n    $block = $page->buildContentBlock();\n}","preventionTips":["Treat unserialization as fallible: always pair fromArray() with a rebuild path.","Log the chained previous exception — the wrapper message alone hides the cause.","Clear caches on deploy so stale serialized blocks never reach production code."],"tags":["php","grav","content-block","unserialization","wrapper-exception"],"backgroundTag":"unserialize-invalid-data","analyzedSha":"6040efed04efa69b8209448ed81308e7c24147c2","analyzedAt":"2026-08-17T05:07:31.593Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}