← All Tools

{{variable}} Works but [variable] Doesn't

Guide · Last verified Aug 21, 2026

Grab prompt templates from all over and you learn that variable notation is different in every tool. Some use {{variable}}, some {variable}, and some docs mark it [variable]. Feed a square-bracket template into the prompt variable extractor and nothing gets extracted — and that's not a bug, it's intended design. Here's why square brackets specifically were left out, dissecting the actual regex structure.

1. Why variable syntax differs by tool

Prompt variable notation has never had a standard. Each ecosystem just brought over its own language's string-substitution syntax. {{variable}} (double curly braces) is the standard in LangChain's PromptTemplate, Jinja2, and Handlebars.js; {variable} (single curly brace) is common in Python's str.format() and f-string family; $variable is used in Python's string.Template and shell script pipelines; percent constructs like {% for %} are used in advanced Jinja2 templates needing loops and conditionals. So "which syntax you use" is also a trace of which framework the prompt passed through.

2. Verifying the supported range from the actual regex

The tool's variable-finding logic is just these two regexes.

Actual code
/\{\{(\w+)\}\}/g — captures double curly braces
/\{(\w+)\}/g — captures single curly braces

The regex itself has no pattern for handling square brackets [ ] at all. So "low recognition rate" is wrong — "not a target of the check in the first place" is the accurate description. Interestingly, the two regexes overlap. The string {{role}} matches the double-brace regex, but the single-brace regex also separately matches the inner {role} part. The reason results aren't duplicated is that the extracted values go into a Set (deduplicating collection), not an array. Even when the two regexes overlap, only one "role" remains in the final result.

3. The real reason square brackets are left out: clash with markdown

The reason square-bracket syntax [variable] wasn't included isn't that it's technically impossible — it's that supporting it dramatically raises the risk of misbehavior. Square brackets are already used in two common text syntaxes.

If [variable] were supported as variable syntax, perfectly fine text like [source](https://example.com) or [1] in a prompt pasted straight from a GPT answer would all be misrecognized as "variables." An input field asking for a value would appear that the user didn't want, and in the worst case the link's display text would be wholesale replaced with something else. So the lack of square-bracket support isn't a performance limitation — it's a deliberate choice to avoid wrongly touching actual text.

4. A misbehavior scenario in numbers

Below is an example of a frequently used meeting-notice prompt. Here's what goes wrong assuming square brackets were also recognized as variables.

SourceCurrent (no square-bracket support)If square brackets were supported
Dear {{name}}, meeting notice1 variable: name1 variable: name (same)
For details see [minutes](https://x.com/notes)No change, link kept as-isMisrecognized as variable → "minutes" input field created, entering a value breaks the link text
Check [1] for referencesNo change, footnote number keptMisrecognized as variable "1" → if not filled in, the source stays as-is and confuses the user

As the table shows, there's only 1 real variable, but recognizing square brackets adds 2 more false positives. The false-positive rate in a single prompt spikes to 66% (2 of 3), so not supporting it is the reasonable default.

5. How to name variables safely

The capture group is \w+, and in JavaScript regex \w means [A-Za-z0-9_] — that is, only ASCII letters, digits, and underscore. Non-ASCII letters, spaces, and hyphens (-) aren't included. So a name with a space like {{user name}} breaks the regex at that point and fails to be recognized whole, and a variable name made purely of non-ASCII characters isn't extracted because \w doesn't match those characters. To use it safely, name variables with a combination of ASCII letters, digits, and underscore like {{role}}, {{user_name}}, or if you must use non-ASCII, add an ASCII prefix like {{role1}}.

How to verify: run [..."{{role}}".matchAll(/\{\{(\w+)\}\}/g)] in the browser console and it correctly captures "role"; running it against a non-ASCII-only name returns an empty array [].

Frequently Asked Questions

Q. What if I really have to use [variable]?

A. The simplest way is to replace [variable] with {{variable}} or {variable} before pasting. If you're building a template from scratch, use curly-brace syntax from the start.

Q. Can I mix {{variable}} and {variable} in one template?

A. Yes. The two regexes operate independently and results are merged into a Set, so mixing them still extracts everything correctly. For readability, though, standardize on one syntax within a project.

Q. Are syntaxes like $variable or {% %} supported?

A. No. This tool's extraction logic uses only the two regexes for {{variable}} and {variable} — dollar signs and Jinja2 control constructs (loops, conditionals) aren't checked at all. Templates written in other syntax must first be converted to curly-brace form.

Q. If the same variable appears multiple times, do I get multiple input fields?

A. No. Duplicates are removed via a Set, so the input field is generated only once, and entering a value applies it to every position in the template simultaneously.