{"record":{"id":"0e60e6b1f05b9961","repo":"twigphp/Twig","slug":"unexpected-character-s","errorCode":null,"errorMessage":"Unexpected character \"%s\".","messagePattern":"Unexpected character \"(.+?)\"\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/Lexer.php","lineNumber":423,"sourceCode":"            $this->pushToken(Token::STRING_TYPE, $this->stripcslashes($this->normalizeNewlines(substr($match[0], 1, -1)), substr($match[0], 0, 1)));\n            $this->moveCursor($match[0]);\n        }\n        // opening double quoted string\n        elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) {\n            $this->brackets[] = ['\"', $this->lineno];\n            $this->pushState(self::STATE_STRING);\n            $this->moveCursor($match[0]);\n        }\n        // inline comment\n        elseif (preg_match(self::REGEX_RAW_INLINE_COMMENT, $this->code, $match, 0, $this->cursor)) {\n            if (str_starts_with($match[0], '##')) {\n                $this->addDocumentation(substr($match[0], 2));\n            }\n            $this->moveCursor($match[0]);\n        }\n        // unlexable\n        else {\n            throw new SyntaxError(\\sprintf('Unexpected character \"%s\".', $this->code[$this->cursor]), $this->lineno, $this->source, columnno: $this->source->getColumn($this->cursor));\n        }\n    }\n\n    private function stripcslashes(string $str, string $quoteType): string\n    {\n        $result = '';\n        $length = \\strlen($str);\n\n        $i = 0;\n        while ($i < $length) {\n            if (false === $pos = strpos($str, '\\\\', $i)) {\n                $result .= substr($str, $i);\n                break;\n            }\n\n            $result .= substr($str, $i, $pos - $i);\n            $i = $pos + 1;\n","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Lexer.php#L405-L441","documentation":"Inside an expression (`{{ ... }}` or `{% ... %}`), the Lexer encountered a character it cannot match against any known token regex (name, number, string, operator, punctuation). It reports the offending character plus line and column. This is Twig's fallback 'unlexable' branch in lexExpression.","triggerScenarios":"Any character outside Twig's expression grammar appears inside a tag, e.g. '{{ 1 @ 2 }}', '{{ \"unterminated }}', a stray backslash, or a mis-encoded/UTF-8 byte sequence that matches no token pattern.","commonSituations":"Typos like `{{ price }€}`; pasting code from other templating languages (Handlebars `{{#if}}`); broken multibyte characters after a bad encoding conversion; using reserved punctuation in variable names.","solutions":["Go to the reported line/column and remove or correct the offending character.","Quote any literal text: move it outside the `{{ }}` expression or into a string.","Verify the template file encoding is valid UTF-8 without stray control bytes.","If migrating from another engine, convert foreign syntax (e.g. Handlebars helpers) to Twig equivalents."],"exampleFix":"// before\n{{ 100 € total }}\n\n// after\n{{ 100 }} € total","handlingStrategy":"validation","validationCode":"// pre-scan expression contents for characters outside Twig's token alphabet\nif (preg_match('/\\{\\{[^}]*[@#$\\\\][^}]*\\}\\}/', $code, $m)) {\n    trigger_error('Suspicious character in expression: '.$m[0], E_USER_WARNING);\n}","typeGuard":null,"tryCatchPattern":"try {\n    $twig->render($name, $context);\n} catch (\\Twig\\Error\\SyntaxError $e) {\n    log('Unexpected character at '.$e->getTemplateLine().':'.$e->getTemplateLine());\n}","preventionTips":["Quote all literal text; keep punctuation outside {{ }} expressions.","Ensure template files are valid UTF-8.","Lint templates with twig-lint in the build pipeline."],"tags":["lexer","template","syntax-error","twig"],"backgroundTag":"template-syntax-error","analyzedSha":"a414c3a491defb5a60f2fc88ef79ff37c90010cd","analyzedAt":"2026-09-13T15:10:46.849Z","contentChangedAt":"2026-09-13T15:10:46.849Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}