{"record":{"id":"aa916c4b46a31c7e","repo":"twigphp/Twig","slug":"invalid-escaping-strategy-s-valid-ones-s","errorCode":null,"errorMessage":"Invalid escaping strategy \"%s\" (valid ones: \"%s\").","messagePattern":"Invalid escaping strategy \"(.+?)\" \\(valid ones: \"(.+?)\"\\)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/Runtime/EscaperRuntime.php","lineNumber":328,"sourceCode":"                }, $string);\n\n                if ('UTF-8' !== $charset) {\n                    $string = iconv('UTF-8', $charset, $string);\n                }\n\n                return $string;\n\n            case 'url':\n                return rawurlencode($string);\n\n            default:\n                if (\\array_key_exists($strategy, $this->escapers)) {\n                    return $this->escapers[$strategy]($string, $charset);\n                }\n\n                $validStrategies = implode('\", \"', array_merge(['html', 'js', 'url', 'css', 'html_attr', 'html_attr_relaxed'], array_keys($this->escapers)));\n\n                throw new RuntimeError(\\sprintf('Invalid escaping strategy \"%s\" (valid ones: \"%s\").', $strategy, $validStrategies));\n        }\n    }\n\n    private function convertEncoding(string $string, string $to, string $from)\n    {\n        if (!\\function_exists('iconv')) {\n            throw new RuntimeError('Unable to convert encoding: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.');\n        }\n\n        return iconv($from, $to, $string);\n    }\n}\n","sourceCodeStart":310,"sourceCodeEnd":341,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Runtime/EscaperRuntime.php#L310-L341","documentation":"EscaperRuntime::escape() throws this when the requested escaping strategy name is neither one of the built-ins (html, js, url, css, html_attr, html_attr_relaxed) nor a key registered via registerEscaper(). It fails fast rather than falling back to a default strategy.","triggerScenarios":"Passing a typo'd or nonexistent strategy string: |escape('htm'), escape($env, $s, 'HTML_ATTR') (lookups are case-sensitive), a strategy variable resolved at runtime that is empty/null-derived, or referencing a custom escaper before registerEscaper() was called on the runtime.","commonSituations":"Strategy chosen dynamically from config or user input; upgrading Twig where a strategy was renamed; forgetting to register a custom escaper before rendering.","solutions":["Check spelling/case against the valid list: html, js, url, css, html_attr, html_attr_relaxed.","Register the intended custom escaper with $runtime->registerEscaper($name, $callable) before escaping.","Default to 'html' when the strategy is dynamic: $strategy = $allowed[$input] ?? 'html'.","Validate the strategy against an allowlist before passing it to escape()."],"exampleFix":"// before\n {{ value|escape(strategy) }} {# strategy = 'htm' #}\n// after\n {% set strategy = strategy in ['html','js','url','css','html_attr','html_attr_relaxed'] ? strategy : 'html' %}\n {{ value|escape(strategy) }}","handlingStrategy":"validation","validationCode":"const VALID = ['html','js','url','css','html_attr','html_attr_relaxed'];\nif (!in_array($strategy, VALID, true) && !array_key_exists($strategy, $escapers)) {\n    throw new \\InvalidArgumentException(\"Unknown strategy $strategy\");\n}","typeGuard":"function isTwigStrategy(string $s): bool {\n    return in_array($s, ['html','js','url','css','html_attr','html_attr_relaxed'], true);\n}","tryCatchPattern":"try {\n    $out = $escaper->escape($env, $value, $strategy);\n} catch (\\Twig\\Error\\RuntimeError $e) {\n    if (str_starts_with($e->getMessage(), 'Invalid escaping strategy')) {\n        $out = $escaper->escape($env, $value, 'html');\n    } else { throw $e; }\n}","preventionTips":["Use an enum/const list of strategies instead of free-form strings.","Never pass user-controlled values directly as the strategy.","Register custom escapers during bootstrap, before any render.","Match strategy casing exactly — lookups are case-sensitive."],"tags":["twig","escaping","invalid-argument"],"backgroundTag":"invalid-enum-value","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"}