Bash syntax error: unexpected `then`

Bash trips on "unexpected token then" when `if` is missing the terminator on the condition line. Add a semicolon or move `then` to its own line.

Error String

bash: syntax error near unexpected token `then'

Tldr

Bash needs a terminator (semicolon or newline) between the `if` condition and the `then` keyword. Missing it is the #1 cause of this error.

Cause

The `if` keyword takes a command list, followed by a separator, followed by `then`. Without the separator the parser reads `[ "$x" = 1 ] then` as one command and reports `then` as unexpected.

Repro

if [ "$x" = 1 ] then          # syntax error
  echo "one"
fi

Fix

if [ "$x" = 1 ]; then           # semicolon
  echo "one"
fi

# Or use a newline:
if [ "$x" = 1 ]
then
  echo "one"
fi

Explanation

The same rule applies to `while`, `until`, and `for` — each needs `; do` or a newline before `do`.

Faq

Q

Is `then` on the next line equivalent to `; then`?

A

Yes. A newline is a command separator, so both forms are correct; `; then` is just the compact style.

Q

Why does the error point at the last line of my script?

A

The parser only fails when input runs out, so it reports the end of the file rather than the line missing the separator.

Deep Dive

Heading

Bash needs a command separator before then

Body

`if` takes a list of commands, and `then` must start a new command. That means a newline or a semicolon after the condition: `if [ -f "$f" ]; then` or `then` on its own line. Writing `if [ -f "$f" ] then` makes `then` just another argument to the test, so Bash reads on until the end of the construct and reports the missing keyword — often pointing at a line far below the real mistake.

Heading

The error line is rarely the broken line

Body

Because the parser only notices when it runs out of input, the reported line number is where the construct ended, not where the separator was omitted. Work backwards through open `if`, `while`, `for`, `case` and function bodies from that point. Consistent indentation makes the missing branch obvious, and `bash -n script.sh` parses without executing anything so you can iterate safely. An editor with shell syntax highlighting usually colours the stray `then` differently as soon as you type it.

Checklist

Add `;` before `then` or move `then` to its own line.

Run `bash -n script.sh` to re-check syntax without executing.

Search upward from the reported line for an unterminated `if` or loop.

Check for a `fi` you deleted while editing a nested branch.