phalcon/cphalcon · error · Phalcon\Cli\Router\Exceptions\InvalidRoutePaths

The route contains invalid paths ('{pattern}')

Error message

The route contains invalid paths ('{pattern}')

What it means

When a CLI route's paths define a namespaced task (task name containing a backslash), Phalcon splits it with get_class_ns()/get_ns_class() to derive the namespace and the bare task name. If either half comes back null — the string does not decompose into namespace + class name — InvalidRoutePaths is thrown with the route pattern.

Source

Thrown at phalcon/Cli/Router/Route.zep:460

            let routePaths = [];

            // Process module name
            if moduleName !== null {
                let routePaths["module"] = moduleName;
            }

            // Process task name
            if taskName !== null {
                // Check if we need to obtain the namespace
                if memstr(taskName, "\\") {
                    // Extract the real class name from the namespaced class
                    let realClassName = get_class_ns(taskName);

                    // Extract the namespace from the namespaced class
                    let namespaceName = get_ns_class(taskName);

                    if unlikely (namespaceName === null || realClassName === null) {
                        throw new InvalidRoutePaths(pattern);
                    }

                    // Update the namespace
                    if namespaceName {
                        let routePaths["namespace"] = namespaceName;
                    }
                } else {
                    let realClassName = taskName;
                }

                // Always pass the task to lowercase
                let routePaths["task"] = uncamelize(realClassName);
            }

            // Process action name
            if actionName !== null {
                let routePaths["action"] = actionName;
            }

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Remove leading/trailing backslashes: ['task' => 'App\Tasks\Main']
  2. Or specify namespace and task separately: ['namespace' => 'App\Tasks', 'task' => 'main']
  3. Keep task names un-namespaced and pass the namespace under its own 'namespace' path key

Example fix

// before
$router->add('/jobs', ['task' => '\App\Tasks\Main']);

// after
$router->add('/jobs', ['namespace' => 'App\Tasks', 'task' => 'main']);
Defensive patterns

Strategy: validation

Validate before calling

function assertValidTaskName(string $task): void
{
    if (strpos($task, '\\') !== false &&
        !preg_match('/^[A-Za-z_][A-Za-z0-9_]*(\\[A-Za-z_][A-Za-z0-9_]*)+$/', $task)) {
        throw new InvalidArgumentException('Malformed namespaced task: ' . $task);
    }
}
assertValidTaskName($task);
$router->add('/jobs', ['task' => $task]);

Type guard

/**
 * A namespaced task must decompose into namespace + class name:
 * no leading/trailing backslash, no empty segments.
 */
function isDecomposableTaskName(string $task): bool
{
    return preg_match('/^[A-Za-z_][A-Za-z0-9_]*(\\[A-Za-z_][A-Za-z0-9_]*)+$/', $task) === 1;
}

Try / catch

try {
    $router->add($pattern, $paths);
} catch (\Phalcon\Cli\Router\Route\Exception\InvalidRoutePaths $e) {
    // Falls through when namespace/class extraction from the task name fails.
    // Split 'App\Tasks\Main' into namespace + task keys and retry.
    $parts = explode('\\', trim($paths['task'], '\\'));
    $task = array_pop($parts);
    $router->add($pattern, ['namespace' => implode('\\', $parts), 'task' => $task]);
}

Prevention

When it happens

Trigger: $router->add('/jobs', ['task' => '\Tasks\Main']) with a leading backslash, 'App\Tasks\' with a trailing backslash, or a lone '\' — none decompose into a namespace plus a real class name.

Common situations: Copying fully-qualified class names with the leading \ exactly as written in PHP source into route paths; concatenating namespace constants ('NS . '\Tasks\' style) that leave empty segments.

Related errors


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