phalcon/cphalcon · error · Phalcon\Support\Helper\Str\Exceptions\SyntaxError

Syntax error in string '{text}'

Error message

Syntax error in string '{text}'

What it means

Phalcon\Support\Helper\Str\Dynamic expands placeholder groups such as '{Hello|Hi} {world}' into every combination. Before matching it compares mb_substr_count() of the left vs right delimiter; a mismatch means a placeholder is unclosed or the content contains stray delimiters, and it throws Phalcon\Support\Helper\Str\Exceptions\SyntaxError ("Syntax error in string '{text}'"). Delimiters are configurable (defaults '{' and '}').

Source

Thrown at phalcon/Support/Helper/Str/Dynamic.zep:36

 * by the separator
 */
class Dynamic
{
    /**
     * @phpstan-param non-empty-string $separator
     */
    public function __invoke(
        string text,
        string leftDelimiter = "{",
        string rightDelimiter = "}",
        string separator = "|"
    ) -> string
    {
        var ldS, rdS, matches, match, words, word, sub;
        string pattern;

        if unlikely mb_substr_count(text, leftDelimiter) !== mb_substr_count(text, rightDelimiter) {
            throw new SyntaxError(text);
        }

        let ldS = preg_quote(leftDelimiter),
            rdS = preg_quote(rightDelimiter),
            pattern = "/" . ldS . "([^" . ldS . rdS . "]+)" . rdS . "/",
            matches = [];

        if !preg_match_all(pattern, text, matches, 2) {
            return text;
        }

        if typeof matches == "array" {
            for match in matches {
                if !isset match[0] || !isset match[1] {
                    continue;
                }

                let words = explode(separator, match[1]),

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Balance the delimiters — every '{' needs its matching '}'
  2. For content with literal braces, switch to delimiters that cannot occur in it: (new Dynamic())($text, '{{', '}}') or ('<', '>')
  3. Strip or escape stray delimiters from user input before processing

Example fix

// before
$variants = (new Dynamic())('Hello {name'); // 1 '{' vs 0 '}' -> SyntaxError

// after
$variants = (new Dynamic())('Hello {name}'); // balanced
Defensive patterns

Strategy: validation

Validate before calling

$left  = mb_substr_count($text, '{');
$right = mb_substr_count($text, '}');

$result = ($left === $right)
    ? (new \Phalcon\Support\Helper\Str\Dynamic())($text)
    : str_replace(['{', '}'], '', $text); // or log and reject

Type guard

function hasBalancedDelimiters(string $text, string $left = '{', string $right = '}'): bool
{
    return mb_substr_count($text, $left) === mb_substr_count($text, $right);
}

Try / catch

use Phalcon\Support\Helper\Str\Exceptions\SyntaxError;

try {
    $variants = (new Dynamic())($text);
} catch (SyntaxError $e) {
    // message embeds the offending text
    $logger->warning($e->getMessage());
    $variants = [$text];
}

Prevention

When it happens

Trigger: (new Dynamic())('Hello {name') — one '{', zero '}'; text containing literal unbalanced braces ('function() { return 1;'); custom delimiters that collide with characters occurring in the content.

Common situations: Generating message/subject variants from copy written by non-developers who drop a brace; passing snippets of code/CSS/JS through the helper; user-supplied template text with unmatched delimiters.

Related errors


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