ValidationException: Unexpected from source

TL;DR — 你 PartiQL FROM 子句裡的表名含有解析器不接受的裸字元——通常是短橫線。把名字用雙引號包起來(SELECT * FROM "my-table")。單引號不行:在 PartiQL 裡它表示字串字面量,而不是識別符號。

這是什麼意思

ValidationException: Unexpected from source

PartiQL 解析器把 FROM my-table 讀成識別符號 my 後面跟著一堆意外的詞法單元——短橫線在裸識別符號裡是不合法的。DynamoDB 的表名合法地可以包含 -._,所以一個完全合法的表名在 PartiQL 裡仍然可能無法被解析,直到你給它加上引號。與 PartiQL 關鍵字衝突的名字也是同理。

為什麼會發生

  • 表名含有短橫線或點——users-prodapp.events。裸識別符號帶不了它們。
  • 框架生成的表名——那些把環境或階段名字尾拼到表名上的工具(例如 Todo-dev),是短橫線在你沒主動選擇的情況下混進來的經典途徑。
  • 查詢索引時沒加引號——"table"."index" 這種寫法需要兩部分都加雙引號。
  • 用了單引號而不是雙引號——FROM 'my-table' 同樣會失敗:在 PartiQL 裡單引號表示字串字面量,而不是名字。

如何修正

  1. 給表名加雙引號:

    SELECT * FROM "users-prod" WHERE pk = 'USER#42'
  2. 查詢索引時兩部分都加雙引號:

    SELECT * FROM "users-prod"."email-index" WHERE email = 'ada@example.com'
  3. 單引號只留給字串值——名字用雙引號,值用單引號。把兩者搞混,產生的正是這一類解析錯誤。

  4. 在生成語句時防禦性地加引號——如果你的程式碼把表名插值進 PartiQL,就總是把它們雙引號包起來;即使某個名字嚴格來說並不需要,這麼寫也是合法的。

DynoTable 的 PartiQL 編輯器會替你處理識別符號的引號——針對的正是這一類解析錯誤,並帶內聯診斷和快速修復;而如果你寧願完全繞開 PartiQL 的解析,DynamoDB Expression Builder 會給出等價的原生 Query/Scan 請求。

在 DynoTable 中執行

DynoTable 的 PartiQL 編輯器會自動用雙引號引用表和索引名稱 — 在將語句貼上到 SDK 程式碼中之前執行 SELECT * FROM "my-table" 並進行內聯診斷。使用 ⌘K 開啟表格,從側邊欄確認確切的表格名稱(包括破折號)。當 PartiQL 解析持續失敗時,切換到 Query Builder 以獲得等效的本機請求。Settings → Profiles上的 Profile 切換 (⌘P) 和 Test Connection 使語句保持指向正確的表。參見連線 AWS安裝

來源

重現方式

PartiQL 語句,其 FROM 源不是表名。解析器在查詢表之前會拒絕它,因此這會在任何端點上重現:

await client.send(new ExecuteStatementCommand({Statement: 'SELECT * FROM 123'}));

實際輸出:

ValidationException: Unexpected from source
HTTP 400

將其與未加引號但有效的名稱進行對比:SELECT * FROM repro 解析得很好,如果不存在這樣的表,則稍後會失敗,並使用 ResourceNotFoundExceptionUnexpected from source 嚴格來說是一個 解析 失敗,因此將其視為語法訊號,而不是缺失表訊號。

相關錯誤

參考資料

最後核實於 2026-07-13,依據上方連結的 AWS 官方文件。

2026-07-26 針對 DynamoDB Local 2.x 與 AWS SDK for JavaScript v3.1095.0 復現——上方輸出為原樣照錄。

不必透過主控台就能操作 DynamoDB

一款快速的 DynamoDB 桌面用戶端,可執行 DynamoDB 無法執行的真正 SQL — JOINs、GROUP BY、聚合 — 並支援視覺化編輯與使用你自己的 Bedrock 金鑰的 AI 代理。

30 天免費試用,無需信用卡 — 之後為無時間限制的免費方案。