You paste a command. The terminal refuses to run it.
You copy a command from the Go documentation. You paste it into your terminal and hit Enter. The shell responds with syntax error: unexpected semicolon or newline. You look at the line. It seems perfect. There is a semicolon where it should be. The newline is just the end of the line. The computer refuses to cooperate.
This error almost never comes from Go. It comes from the shell. Bash, Zsh, PowerShell, or whatever command-line interface you are using parses your input before Go ever sees it. If the shell cannot figure out where one command ends and the next begins, it throws this error. The shell is a strict grammarian. It expects commands to follow a specific structure. A stray character, a missing quote, or a hidden line break breaks the grammar, and the shell stops parsing immediately.
The shell parses before Go runs
When you type a command, the shell breaks it into tokens. Spaces separate arguments. Semicolons separate commands. Newlines usually separate commands too. Quotes tell the shell to treat everything inside as a single argument, ignoring spaces and special characters.
If you open a quote but forget to close it, the shell keeps reading. It treats the newline as part of the string. When you finally type the closing quote, the shell might be in a state where it expects a semicolon but sees something else. The parser gets out of sync. The error message points to the location where the shell realized the structure was broken, which is often not where the mistake actually happened.
Go does not care about semicolons or newlines in your source code. The Go compiler handles whitespace automatically. The shell cares deeply. The shell is the environment that launches Go. You have to speak the shell's language to get Go running.
Quotes group tokens and protect special characters
The most common cause of this error is missing or mismatched quotes. Arguments that contain spaces, equals signs, or special characters must be quoted. If you leave them unquoted, the shell splits the argument at every space. The resulting tokens confuse the parser.
# This fails because the shell splits the value at the space.
# The shell sees "export" as the command, "GODEBUG=tarinsecurepath" as an argument,
# and "0" as a separate command, which causes a syntax error or "command not found".
export GODEBUG=tarinsecurepath 0
# This works. The quotes group the entire value into a single token.
# The shell passes "tarinsecurepath=0" as the value for GODEBUG.
export GODEBUG="tarinsecurepath=0"
Double quotes allow variable expansion. Single quotes treat everything literally. Pick the right one for the job. If you use double quotes, the shell replaces $VAR with its value before passing the string. If you use single quotes, the shell passes $VAR as literal text.
# Double quotes expand variables.
# If VERSION is "1.0", this sets GODEBUG to "version=1.0".
export GODEBUG="version=$VERSION"
# Single quotes preserve the dollar sign.
# This sets GODEBUG to the literal string "version=$VERSION".
export GODEBUG='version=$VERSION'
The shell is a parser, not a helper. Feed it clean tokens.
Hidden characters and line endings break scripts
Copy-pasting from websites or word processors introduces invisible characters that break shell syntax. Websites often use "smart quotes" for typography. These are curly characters like " and '. The shell expects straight ASCII quotes like " and '. If you paste smart quotes, the shell sees a character it does not recognize as a delimiter. It treats the curly quote as part of the variable name or value. The parser gets confused and throws a syntax error.
# This fails. The quotes are curly Unicode characters, not ASCII quotes.
# The shell does not recognize them as delimiters.
# It sees the curly quote as part of the text, breaking the command structure.
export GODEBUGοΌ"tarinsecurepath=0"
# This works. Straight quotes tell the shell where the value starts and ends.
export GODEBUG="tarinsecurepath=0"
Line endings differ between operating systems. Windows uses carriage return plus line feed (CRLF). Linux and macOS use just line feed (LF). If you write a script on Windows and run it on Linux, the shell sees the carriage return as part of the command. It might interpret then\r as a variable name or a command, breaking the syntax. The error message might mention a semicolon or newline because the parser is confused by the extra character.
# This script fails on Linux if it has Windows line endings.
# The shell sees "then\r" and does not recognize it as the keyword "then".
# It throws a syntax error near the unexpected token.
if [ -f file.txt ]; then
echo "file exists"
fi
Convert line endings before running scripts across systems. Use dos2unix script.sh to fix CRLF files. Use cat -A script.sh to reveal hidden characters. The ^M symbol at the end of lines indicates carriage returns.
Smart quotes are for documents, not terminals
Websites love typography. They replace straight quotes with curly quotes to make text look better. Your terminal does not care about typography. It cares about ASCII. If you copy a command from a blog post, a PDF, or a formatted document, check the quotes. If they curve, retype them manually.
This applies to other characters too. Dashes can be en-dashes or em-dashes. The shell expects hyphens. Apostrophes can be curly. The shell expects straight apostrophes. Retyping the command is faster than hunting for invisible Unicode characters.
Spaces break assignments
In Go, spaces do not matter around operators. In the shell, spaces matter everywhere. An assignment must have no spaces around the equals sign. If you add spaces, the shell interprets the parts as separate commands.
# This fails. The shell sees "export" as the command, "GODEBUG" as an argument,
# "=" as a command (which fails), and "value" as an argument.
# You get a syntax error or "command not found".
export GODEBUG = tarinsecurepath=0
# This works. No spaces around the equals sign.
export GODEBUG=tarinsecurepath=0
The shell treats = as part of the assignment syntax only when it is attached to the variable name. Spaces break that syntax. The shell tries to run = as a command, which causes an error.
Decision: when to use quoting and debugging tools
Use double quotes when the value contains spaces or variables you want expanded. Use single quotes when you need literal text with no variable expansion. Use a semicolon when you want to chain commands on one line. Use a newline when you want to separate commands for readability. Use dos2unix when you move scripts between Windows and Unix systems. Use cat -A when you suspect hidden characters are breaking your script. Use straight ASCII quotes when copying from formatted documents. Retype the command manually if the shell rejects characters that look correct.