{"record":{"id":"9de4ee6ad7b45ab8","repo":"getgrav/grav","slug":"500-9de4ee","errorCode":"500","errorMessage":"Not Implemented","messagePattern":"Not Implemented","errorType":"http","errorClass":"RuntimeException","httpStatus":500,"severity":"error","filePath":"system/src/Grav/Framework/Media/MediaObject.php","lineNumber":125,"sourceCode":"     *\n     * @param array $actions\n     * @return Response\n     */\n    public function createResponse(array $actions): ResponseInterface\n    {\n        if (!isset($this->media)) {\n            return $this->create404Response($actions);\n        }\n\n        $media = $this->media;\n\n        if ($actions) {\n            $media = $this->processMediaActions($media, $actions);\n        }\n\n        // FIXME: This only works for images\n        if (!$media instanceof ImageMedium) {\n            throw new \\RuntimeException('Not Implemented', 500);\n        }\n\n        $filename = $media->path(false);\n        $time = filemtime($filename);\n        $size = filesize($filename);\n        $body = fopen($filename, 'rb');\n        $headers = [\n            'Content-Type' => $media->get('mime'),\n            'Last-Modified' => gmdate('D, d M Y H:i:s', $time) . ' GMT',\n            'ETag' => sprintf('%x-%x', $size, $time)\n        ];\n\n        return new Response(200, $headers, $body);\n    }\n\n    /**\n     * Process media actions\n     *","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/getgrav/grav/blob/6040efed04efa69b8209448ed81308e7c24147c2/system/src/Grav/Framework/Media/MediaObject.php#L107-L143","documentation":"MediaObject::createResponse() turns a media object into an HTTP response after applying medium actions (resize etc.). The source marks the limitation with a FIXME: the response path (filemtime/filesize/streaming with Content-Type, Last-Modified, ETag) is only implemented for ImageMedium instances. Any other medium (video, audio, PDF, or a media object whose file is missing) causes RuntimeException('Not Implemented', 500).","triggerScenarios":"Requesting a media URL that triggers actions/responses for a non-image file, e.g. a video or PDF passed through a route that calls createResponse(); applying image-style actions to a non-image medium and then rendering the response; the media field resolving to a missing file so $this->media is unset for that type of flow combined with action parameters.","commonSituations":"Theme/template code reusing image-handling logic (thumbnails, resize filters) for arbitrary uploaded files; users uploading videos/PDFs into a media field that the template feeds into the media response API; upgrading Grav where such calls previously fell through to another code path.","solutions":["Before triggering the response path, branch on the medium type and only use createResponse() for images (instanceof ImageMedium / getMime starting with 'image/').","For non-image files, serve the original file or link directly (e.g. $media->url()) instead of the actions/response pipeline.","If actions like resize are needed for videos, use ffmpeg-based or plugin-provided pipelines rather than Grav's image medium actions.","Ensure the referenced file actually exists in the media folder so $this->media is set; otherwise you get the 404 branch instead of a broken response."],"exampleFix":"// before\n$response = $mediaObject->createResponse($actions); // video -> RuntimeException('Not Implemented', 500)\n\n// after\n$media = $mediaObject->getMedia();\nif ($media instanceof \\Grav\\Common\\Page\\Medium\\ImageMedium) {\n    $response = $mediaObject->createResponse($actions);\n} else {\n    $response = new \\Grav\\Framework\\Response($media ? $media->url() : '/fallback-file.png', 302);\n}","handlingStrategy":"type-guard","validationCode":"$media = $mediaObject->getMedia();\nif ($media instanceof \\Grav\\Common\\Page\\Medium\\ImageMedium) {\n    $response = $mediaObject->createResponse($actions);\n} else {\n    // non-image: serve original or redirect\n    $response = $media ? $media->url() : null;\n}","typeGuard":"function mediaSupportsActionResponse(\\Grav\\Framework\\Media\\MediaObjectInterface $object): bool\n{\n    $media = $object->getMedia();\n\n    return $media instanceof \\Grav\\Common\\Page\\Medium\\ImageMedium;\n}","tryCatchPattern":"try {\n    $response = $mediaObject->createResponse($actions);\n} catch (\\RuntimeException $e) {\n    if ('Not Implemented' === $e->getMessage() && $e->getCode() === 500) {\n        // non-image medium: fall back to original file URL or 404\n        $response = $mediaObject->getMedia() ? $mediaObject->getMedia()->url() : '/404-not-found';\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Branch on instanceof ImageMedium (or mime type image/*) before using the actions/response pipeline.","Restrict admin media fields that feed this API to image selections, or handle non-images with direct links.","Test media routes with each file type (jpg, mp4, pdf) your site accepts."],"tags":["media","response","not-implemented","image","grav","http-500"],"backgroundTag":"unsupported-media-type","analyzedSha":"6040efed04efa69b8209448ed81308e7c24147c2","analyzedAt":"2026-08-17T05:07:31.593Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}