phalcon/cphalcon · error · Phalcon\Assets\Exceptions\InvalidTargetPath

Path '{path}' is not a valid target path

Error message

Path '{path}' is not a valid target path

What it means

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.

Source

Thrown at phalcon/Assets/Manager.zep:467

            /**
             * Global filtered content
             */
            let filteredJoinedContent = "";

            /**
             * Check if the collection have its own target base path
             */
            let join = collection->getJoin();

            /**
             * Check for valid target paths if the collection must be joined
             */
            if !join {
                /**
                 * We need a valid final target path
                 */
                if (true === empty(completeTargetPath)) {
                    throw new InvalidTargetPath(completeTargetPath);
                }

                if (true === is_dir(completeTargetPath)) {
                    throw new TargetPathIsDirectory(completeTargetPath);
                }
            }
        }

        /** @var Asset $asset */
        for asset in assets {
            let filterNeeded = false;

            /**
             * If the collection must not be joined we must print a HTML for
             * each one
             */
            if (true !== empty(filters)) {
                let sourcePath = asset->getPath();

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Give the filtered output a destination: `$collection->setTargetPath('css/out.css')` (or per-asset `setTargetPath()`)
  2. Set the global output base: pass `'targetBasePath' => '/app/public/'` in the Manager options or to outputCss()/outputJs()
  3. Or re-enable joining: `$collection->setJoin(true)` so one combined file is written
  4. Remove the filters if no transformation is actually needed — unfiltered, non-joined assets print HTML without touching disk

Example fix

// before
$css = $assets->collection('header');
$css->setJoin(false)->addFilter(new \Phalcon\Assets\Filters\Cssmin());
echo $assets->outputCss('header');
// after
$css = $assets->collection('header');
$css->setJoin(false)
    ->setTargetPath('css/header/')
    ->addFilter(new \Phalcon\Assets\Filters\Cssmin());
echo $assets->outputCss('header');
Defensive patterns

Strategy: validation

Validate before calling

if (!$collection->getJoin() && count($collection->getFilters()) > 0) {
    if ('' === trim((string) $collection->getTargetPath()) && '' === trim((string) $targetBasePath)) {
        throw new RuntimeException('Filtered non-joined collection needs a target path: ' . $name);
    }
}
echo $assets->outputCss($name);

Try / catch

try {
    echo $assets->outputCss('header');
} catch (\Phalcon\Assets\Exceptions\InvalidTargetPath $e) {
    $logger->error('Asset target path misconfigured: ' . $e->getMessage());
    throw $e;
}

Prevention

When it happens

Trigger: 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()`.

Common situations: 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'.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/c855c948016cd62d. Report an issue: GitHub.