{"record":{"id":"c855c948016cd62d","repo":"phalcon/cphalcon","slug":"path-path-is-not-a-valid-target-path","errorCode":null,"errorMessage":"Path '{path}' is not a valid target path","messagePattern":"Path '(.+?)' is not a valid target path","errorType":"exception","errorClass":"Phalcon\\Assets\\Exceptions\\InvalidTargetPath","httpStatus":null,"severity":"error","filePath":"phalcon/Assets/Manager.zep","lineNumber":467,"sourceCode":"            /**\n             * Global filtered content\n             */\n            let filteredJoinedContent = \"\";\n\n            /**\n             * Check if the collection have its own target base path\n             */\n            let join = collection->getJoin();\n\n            /**\n             * Check for valid target paths if the collection must be joined\n             */\n            if !join {\n                /**\n                 * We need a valid final target path\n                 */\n                if (true === empty(completeTargetPath)) {\n                    throw new InvalidTargetPath(completeTargetPath);\n                }\n\n                if (true === is_dir(completeTargetPath)) {\n                    throw new TargetPathIsDirectory(completeTargetPath);\n                }\n            }\n        }\n\n        /** @var Asset $asset */\n        for asset in assets {\n            let filterNeeded = false;\n\n            /**\n             * If the collection must not be joined we must print a HTML for\n             * each one\n             */\n            if (true !== empty(filters)) {\n                let sourcePath = asset->getPath();","sourceCodeStart":449,"sourceCodeEnd":485,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Assets/Manager.zep#L449-L485","documentation":"When a collection has filters and join is disabled, the manager must write the filtered output of each asset to a file; that requires a non-empty final target path (Manager 'targetBasePath' option concatenated with the collection's targetPath). If the combined path is empty the manager throws InvalidTargetPath because it has nowhere to write the filtered file.","triggerScenarios":"A collection with filters (Cssmin/Jsmin or custom) and `$collection->setJoin(false)` (or simply no join) where neither the Manager option 'targetBasePath' nor `$collection->setTargetPath()` is set, followed by `$assets->outputCss()`/`outputJs()`.","commonSituations":"Switching from joined output (one combined file) to per-asset HTML tags and forgetting that filtered assets still need a writable output file each; targetPath configured on some collections only; options array passed to outputCss() with a missing 'targetBasePath'.","solutions":["Give the filtered output a destination: `$collection->setTargetPath('css/out.css')` (or per-asset `setTargetPath()`)","Set the global output base: pass `'targetBasePath' => '/app/public/'` in the Manager options or to outputCss()/outputJs()","Or re-enable joining: `$collection->setJoin(true)` so one combined file is written","Remove the filters if no transformation is actually needed — unfiltered, non-joined assets print HTML without touching disk"],"exampleFix":"// before\n$css = $assets->collection('header');\n$css->setJoin(false)->addFilter(new \\Phalcon\\Assets\\Filters\\Cssmin());\necho $assets->outputCss('header');\n// after\n$css = $assets->collection('header');\n$css->setJoin(false)\n    ->setTargetPath('css/header/')\n    ->addFilter(new \\Phalcon\\Assets\\Filters\\Cssmin());\necho $assets->outputCss('header');","handlingStrategy":"validation","validationCode":"if (!$collection->getJoin() && count($collection->getFilters()) > 0) {\n    if ('' === trim((string) $collection->getTargetPath()) && '' === trim((string) $targetBasePath)) {\n        throw new RuntimeException('Filtered non-joined collection needs a target path: ' . $name);\n    }\n}\necho $assets->outputCss($name);","typeGuard":null,"tryCatchPattern":"try {\n    echo $assets->outputCss('header');\n} catch (\\Phalcon\\Assets\\Exceptions\\InvalidTargetPath $e) {\n    $logger->error('Asset target path misconfigured: ' . $e->getMessage());\n    throw $e;\n}","preventionTips":["Whenever you setJoin(false) on a filtered collection, set a targetPath in the same commit","Configure 'targetBasePath' globally in the Manager options","Add a config lint that walks all collections and asserts filters imply a non-empty target path"],"tags":["assets","target-path","filters","configuration"],"backgroundTag":"empty-target-path","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}