{"record":{"id":"e2542ae34565d3ee","repo":"phalcon/cphalcon","slug":"the-filter-is-not-valid","errorCode":null,"errorMessage":"The filter is not valid","messagePattern":"The filter is not valid","errorType":"exception","errorClass":"Phalcon\\Assets\\Exceptions\\InvalidFilter","httpStatus":null,"severity":"error","filePath":"phalcon/Assets/Manager.zep","lineNumber":880,"sourceCode":"     * @throws InvalidFilter\n     */\n    private function applyFilters(\n        string content,\n        array filters,\n        bool mustFilter = true\n    ) -> string {\n        var filter;\n\n        if (mustFilter !== true) {\n            return content;\n        }\n\n        for filter in filters {\n            /**\n             * Filters must be valid FilterInterface instances\n             */\n            if unlikely (typeof filter !== \"object\" || !(filter instanceof FilterInterface)) {\n                throw new InvalidFilter();\n            }\n\n            /**\n             * Calls the method 'filter' which must return a filtered version\n             * of the content\n             */\n            let content = filter->filter(content);\n        }\n\n        return content;\n    }\n\n    /**\n     * Calculates the prefixed path including the version\n     *\n     * @param Collection $collection\n     * @param string     $path\n     * @param string     $filePath","sourceCodeStart":862,"sourceCodeEnd":898,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Assets/Manager.zep#L862-L898","documentation":"While applying a collection's filters the manager requires every entry to be an object implementing Phalcon\\Assets\\FilterInterface (duck-typed contract with a filter(content) method). A non-object value or a foreign object triggers InvalidFilter, because there is no generic way to invoke an arbitrary value as a filter.","triggerScenarios":"`$collection->addFilter('minify')` (string), `$collection->addFilter(fn($c) => $c)` (closure), or `addFilter(new stdClass())` — then any output/filter operation on the collection.","commonSituations":"Expecting Phalcon\\Filter sanitizer names ('trim', 'lower') to work as asset filters; passing callables the way other libraries accept them; wrapping filter callbacks incorrectly.","solutions":["Use the built-in filters: `new \\Phalcon\\Assets\\Filters\\Cssmin()` / `new \\Phalcon\\Assets\\Filters\\Jsmin()`","Wrap custom logic in a class implementing the interface: `class TrimFilter implements \\Phalcon\\Assets\\FilterInterface { public function filter($content) { ...; return $content; } }`","Audit every addFilter() call site and remove raw strings/closures"],"exampleFix":"// before\n$collection->addFilter('minify');\n// after\n$collection->addFilter(new \\Phalcon\\Assets\\Filters\\Jsmin());\n// or a custom implementation\nfinal class StripCommentsFilter implements \\Phalcon\\Assets\\FilterInterface\n{\n    public function filter(string $content): string\n    {\n        return preg_replace('/\\/\\*.*?\\*\\//s', '', $content);\n    }\n}","handlingStrategy":"type-guard","validationCode":"if (!$filter instanceof \\Phalcon\\Assets\\FilterInterface) {\n    throw new InvalidArgumentException('Asset filters must implement FilterInterface');\n}\n$collection->addFilter($filter);","typeGuard":"function isValidAssetFilter(mixed $filter): bool\n{\n    return is_object($filter) && $filter instanceof \\Phalcon\\Assets\\FilterInterface;\n}","tryCatchPattern":"try {\n    echo $assets->outputJs('app');\n} catch (\\Phalcon\\Assets\\Exceptions\\InvalidFilter $e) {\n    $logger->error('Collection contains a non-FilterInterface filter entry: ' . $e->getMessage());\n    throw $e;\n}","preventionTips":["Only pass FilterInterface instances to addFilter(); wrap custom logic in a small class","Reuse the built-in Cssmin/Jsmin filters for standard minification","Static-analyze filter registration code so string/closure arguments are rejected"],"tags":["assets","filters","interface","type-check"],"backgroundTag":"invalid-filter-type","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}