[Excel/Power Query] Error: Expression.Error — Token Eof Expected (unexpected end) — How to Fix It

Summary

Expression.Error: Token Eof Expected indicates that Power Query’s M parser reached the end of your code but still expected more tokens. Typical causes are unclosed parentheses or brackets, trailing commas after the last element, a missing/duplicated in statement, or stray characters after the final expression. The fastest fix is to open the Advanced Editor, scroll to the bottom, format the code (Ctrl+Shift+F), and balance delimiters. Ensure the query contains exactly one let … in FinalStep block and no text after the final expression.

Context

M code is lenient with whitespace but strict with structure. Each query generally follows the pattern:

let
    Step1 = ...,
    Step2 = ...,
    FinalStep = ...
in
    FinalStep

If any opening delimiter ((, [, {) lacks a matching close, or if a trailing comma suggests more items should follow, the parser anticipates additional tokens and throws “Eof (End of file) Expected.” This appears frequently after copy/pasting between queries, concatenating steps, or editing record/list literals by hand. The error position is often at or near the last lines, but the true cause can be a few characters earlier.

Probable Cause

  • Unclosed delimiters. Missing ), ], or } in nested function calls, records, or lists.
  • Trailing comma at the end of a block. After the last step in let, the last record field, or the final list element.
  • Broken let … in structure. Duplicated in, missing in, or multiple let blocks spliced together incorrectly.
  • Stray characters after the final expression. Extra comments, quotes, or invisible characters (e.g., non-breaking spaces).
  • Partial copy/paste. Code merged without closing previous constructs.

Quick Fix

  1. Open Advanced Editor. Home → Advanced Editor. Scroll to the bottom; most EOF issues surface in the final lines.
  2. Format the code. Press Ctrl+Shift+F to reindent. Misaligned or dangling delimiters become obvious.
  3. Balance delimiters. Count each (, [, { and ensure matching ), ], }.
  4. Remove trailing commas. The last item in a record/list or the final step in let must not end with a comma.
  5. Validate let … in. Exactly one let and one in; the in must reference the final step name.
  6. Delete leftovers after the final expression. No tokens or comments after the in FinalStep line.
// ❌ Trailing comma after FinalStep
let
  Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
  Kept = Table.SelectRows(Source, each [Amount] > 0),
  Final = Table.RemoveColumns(Kept, {"Notes"}),
in
  Final,   // <-- trailing comma causes EOF Expected
// stray text here

// ✅ Correct
let
  Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
  Kept = Table.SelectRows(Source, each [Amount] > 0),
  Final = Table.RemoveColumns(Kept, {"Notes"})
in
  Final

Full Example

Scenario 1: Unclosed parenthesis in a function call.

// ❌ Missing closing )
Filtered = Table.SelectRows(Source, each [Qty] >= 1

// Later...
in
  Filtered
→ Expression.Error: Token Eof Expected

Fix: Close the call and reformat.

Filtered = Table.SelectRows(Source, each [Qty] >= 1)

Scenario 2: Record literal missing closing bracket.

// ❌ Record not closed
Meta = [ Author = "Luis", Year = 2025
in
  Meta
→ EOF Expected near end

Fix: Close with ] and ensure let … in surrounds it.

let
  Meta = [ Author = "Luis", Year = 2025 ]
in
  Meta

Scenario 3: Merging two queries left duplicated let/in.

// ❌ Two blocks concatenated
let
  A = ...,
  B = ...
in
  B
let
  C = Table.AddColumn(B, "Flag", each [Qty] > 0),
  D = Table.RemoveColumns(C, {"Temp"})
in
  D
→ EOF or unexpected tokens (duplicate let/in)

Fix: Combine into a single block.

let
  A = ...,
  B = ...,
  C = Table.AddColumn(B, "Flag", each [Qty] > 0),
  D = Table.RemoveColumns(C, {"Temp"})
in
  D

Scenario 4: Trailing comma in let steps.

// ❌ Trailing comma after final step name
let
  S = ...,
  T = ...,
  U = ...
in
  U,

Fix: Remove the trailing comma.

in
  U

Scenario 5: Stray characters after final expression.

// ❌ Extra characters after 'in FinalStep'
in
  FinalStep )   // <-- extra ')'

Fix: Delete any tokens after the final expression.

Pitfalls & Debug

  • Symptom → Error line highlights the very end. Fix → Check 1–3 lines above for a missing ), ], }, or a trailing comma.
  • Symptom → Formatting fails or doesn’t change much. Fix → Temporarily comment out recent edits with //; reintroduce lines incrementally.
  • Symptom → After pasting JSON, EOF appears. Fix → Convert to M record syntax: use [ Key = Value ] (equals) and commas between fields, not colons only.
  • Symptom → “near in” message. Fix → Ensure exactly one in and that it references an existing step identifier.
  • Symptom → Invisible characters at end. Fix → Backspace the last line fully, retype the in FinalStep, and save.

Validation & Next Steps

After fixing structure, validate deterministically:

1) Ctrl+Shift+F to format; verify balanced indentation.
2) Ensure the final two lines are exactly:
in
    FinalStep
3) Refresh Preview; if another syntax error appears, repeat isolate-and-fix.

Adopt a defensive routine: keep complex expressions in smaller let variables, avoid trailing commas, and prefer UI-generated steps for boilerplate. For collaboration, store a working copy of the query to diff against when EOF errors arise.

Sources

Power Query M language specification

Advanced Editor in Power Query

Power Query M function reference

Labels

Tool/Power Query, OS/Cross-platform, Topic/M Syntax & EOF Parsing