FULL PYTHON FIX · 6 MIN READ

Why Is My Python f-String Printing Curly Braces?

Your output contains {name} instead of the value of name. Diagnose the missing f prefix, then learn when doubled braces are actually needed.

Video guide: Why Is My Python f-String Printing Curly Braces?

The preview is stored on this site. YouTube loads only when you press Play. Watch on YouTube

Read the video transcript

Select a timestamp to watch that moment on YouTube.

  1. 00:00

    A beginner writes a greeting with a variable named name and expects Hello, Ada. The code appears to contain a placeholder between curly braces, so the expected result seems obvious. But when it runs, the screen shows the characters open brace, name, close brace instead of the value. What single character is missing from the source? Pause and inspect the beginning of the quoted string. In this episode we will run the plain string, compare it with an f-string, deliberately escape braces, and verify what happens with a calculated expression. We will also show a case where only one of two neighboring strings has the formatting prefix.

  2. 00:41

    That detail can produce a mixed output that is confusing until you see exactly where Python evaluates each literal. The goal is not to memorize a trick for one greeting. It is to recognize the difference between characters inside a string and expressions that Python has been asked to evaluate. Our debugging approach is the same as in every PythonLessonLab problem guide: predict, run, inspect, make one correction, and test a variation. Start with the exact output and the exact source, not a guess about what the braces ought to mean. Run the program as written. Python prints Hello, open brace name close brace, exclamation point.

  3. 01:23

    The variable name exists and contains Ada, but the quoted text is an ordinary string. In an ordinary string, braces are just characters, much like letters or punctuation. Nothing in this line asks Python to replace them. This is why the program does not raise an error: the characters make valid text. A typical mistake here is to spend time checking the variable assignment or to add a call to str around name. That would not affect what Python does with the already quoted string. The most useful comparison is to print the source with and without an f immediately before the opening quote.

  4. 02:03

    Keep everything else the same and rerun. A one-character change will reveal whether formatting was activated. This also teaches a broader habit: when output is wrong but no exception appears, compare the exact bytes of the expression that produced it with the expression you intended to write. A missing prefix is easy for a person to overlook, especially in a long message. The terminal output is evidence that Python treated the entire placeholder as literal text, not that the variable somehow changed its value. Now print the ordinary string and the f-string on consecutive lines. The first still shows curly braces around name.

  5. 02:44

    The second shows Ada. An f-string is a formatted string literal. The letter f goes immediately before the opening quote, and Python evaluates each expression inside a single pair of braces when that string is created. The expression can be a variable or a small calculation. For example, if score is four, the expression score plus one inserts five. You do not need to convert every integer to text manually; the formatting operation handles that. There is another reason an f-string can display braces. If you write two opening braces and two closing braces, Python interprets that as a request for literal braces.

  6. 03:26

    Test that variation. It prints the placeholder-shaped text even though the f prefix is present. This behavior is useful when you genuinely need braces in a message, such as a template illustration. It is not what you want for substitution. When diagnosing a literal placeholder, therefore check both the prefix and the number of braces. A single brace pair within an f-string evaluates an expression. A doubled pair displays brace characters. An ordinary string never evaluates an expression just because it contains brace characters. Repair the original greeting by adding f directly before the opening quote.

  7. 04:08

    Keep one pair of braces around name. Run the same program and observe Hello, Ada. This is the smallest useful correction. Next, add a number named completed and build one sentence with both values. The output shows Ada completed three lessons. Each pair of braces has its own expression, while the spaces and words outside the braces are plain text. If you split a message across two separately quoted literals, the f prefix does not magically apply to both. Prefix each literal that contains an expression, or keep the formatted parts together in one clear f-string. Also note when the evaluation occurs.

  8. 04:49

    Python substitutes the value as it creates the f-string; if you later change name, an already-created message will not update by itself. To produce a new message, create a new f-string after the value changes. There is no reason to use eval or manual brace replacement for this simple task. The language already provides a readable formatting feature. The fix is small, and we can verify it by checking the exact output rather than merely observing that the code runs without errors. Finish with two contrasting outputs. First print a name and score plus one inside single braces; Python inserts the calculated result.

  9. 05:30

    Then print the literal text brace name brace by using doubled braces inside an f-string. Those results confirm that we understand both substitution and escaping. If an expression inside the braces refers to a name that has not been defined, Python will raise NameError. The f prefix does not invent variables; it simply asks Python to evaluate the expression. That is useful to remember when a previously silent placeholder suddenly becomes an exception after you add the prefix. For your exercise, set name to Sam and attempts to two. Print a sentence saying Sam has three attempts next, using the expression attempts plus one.

  10. 06:12

    On a second line, print the literal placeholder attempts between braces. Predict both lines and then run them. Try removing the f prefix from only one line and explain the changed result. The complete guide on PythonLessonLab includes runnable code, expected output, typical mistakes, and the exercise hint. The String Formatting lesson also has a console, checked task, and quiz. When braces unexpectedly appear in output, inspect the opening quote for f, inspect whether the braces are doubled, and verify the value of the name being formatted.

See the literal placeholder in the output

You want to greet a user by name. The variable contains Ada, but the program prints the letters name between curly braces. Run the two-line program and compare the output with what you predicted. Python did exactly what an ordinary quoted string requests: it kept every character between the quote marks as text.

The braces alone do not make Python evaluate an expression. This mistake is easy to overlook because the source resembles a formatted string. Read the start of the string carefully. There is no f before its opening quote, so this is a plain string literal. Nothing is wrong with the variable assignment, and the braces are not a syntax error in an ordinary string.

The placeholder remains text
PYTHON
name = 'Ada'
print('Hello, {name}!')
OUTPUT
Hello, {name}!

Compare a plain string and an f-string

Print both forms beside each other. The first is a normal string; the second has a lowercase f immediately before the opening quote. In the second form, Python evaluates the expression inside the braces and inserts its formatted value. The expression can be a variable or a simple calculation. You do not need to put str() around every number inside an f-string because formatting handles the conversion.

If the f is present and you still see unexpected text, inspect whether you doubled the braces. In an f-string, doubled opening and closing braces mean that you want literal braces in the output. That feature is useful for showing JSON-like text or documenting a template, but it prevents substitution at that position.

One character changes the behavior
PYTHON
name = 'Ada'
print('Hello, {name}!')
print(f'Hello, {name}!')
OUTPUT
Hello, {name}!
Hello, Ada!
Doubled braces request literal braces
PYTHON
name = 'Ada'
print(f'Hello, {{name}}!')
OUTPUT
Hello, {name}!

Add the prefix and keep one pair of braces

For the original greeting, add f just before the opening quote and keep a single pair of braces around name. Run the same input again. This is the smallest correction and produces Hello, Ada!. When multiple values are needed, each value gets its own expression inside braces; the text outside them remains literal.

The f prefix belongs to each string literal that needs formatting. If you join two quoted strings and only prefix one of them, the other remains plain text. Keep a long message in one readable f-string or prefix every literal that contains expressions. A prefix on a variable name or on print() cannot turn an already-created plain string into an f-string later.

The repaired greeting
PYTHON
name = 'Ada'
print(f'Hello, {name}!')
OUTPUT
Hello, Ada!
Format a number and a name
PYTHON
name = 'Ada'
completed = 3
print(f'{name} completed {completed} lessons.')
OUTPUT
Ada completed 3 lessons.

Test expressions, literal braces, and missing names

Check a second value and a short expression, then deliberately print literal braces. This separates three behaviors: ordinary text, evaluated expressions, and escaped braces. A name used inside an f-string must exist when the string is evaluated. If it does not, Python raises NameError; adding f will reveal that error rather than silently printing the placeholder.

Avoid building code with eval() or replacing braces by hand to solve this formatting problem. An f-string is designed for values already available in your program. For messages supplied by users, keep the text as data and insert only the values you choose. Never execute an untrusted string as Python code just to fill a template.

Verify substitution and escaped braces
PYTHON
name = 'Ada'
score = 4
print(f'{name}: {score + 1} points')
print(f'Literal placeholder: {{name}}')
OUTPUT
Ada: 5 points
Literal placeholder: {name}
  • A plain string keeps {name} as text.
  • An f-string with {name} inserts the current value of name.
  • Doubled braces inside an f-string display literal braces.

Practice the fix

Create name = 'Sam' and attempts = 2. Print exactly Sam has 3 attempts next. using an f-string expression. Then print the literal text {attempts} on a second line using escaped braces. Verify both lines before reading the hint.

Need a hint?

Prefix the quoted string with f. Use {attempts + 1} for the calculation and {{attempts}} when you really want the braces to appear.

Python console

Ready to run

Edit the code and run it in your browser. Examples above can be loaded with Try this example.

Does your code use input()? Add one value per line
Ctrl / ⌘ + Enter to run
OUTPUT
Your output appears here.

Write your solution, then select Check practice.

    Key takeaways

    • Curly braces in an ordinary string are just characters.
    • Put f immediately before the opening quote to evaluate expressions in braces.
    • Use doubled braces only when literal braces are intended.
    • An f-string evaluates names when it is created, so the names must exist.

    Related lessons

    Sources and further reading