ValidationException: Unexpected from source
TL;DR — The table name in your PartiQL FROM clause contains characters the parser won't accept bare — usually a dash. Wrap the name in double quotes (SELECT * FROM "my-table"). Single quotes don't work: in PartiQL they mean a string literal, not an identifier.
What it means
ValidationException: Unexpected from sourceThe PartiQL parser reads FROM my-table as the identifier my followed by unexpected tokens — the dash isn't valid inside a bare identifier. DynamoDB table names may legally contain -, ., and _, so a perfectly valid table name can still be un-parseable in PartiQL until it's quoted. The same applies to names that collide with PartiQL keywords.
Why it happens
- The table name contains a dash or dot —
users-prod,app.events. Bare identifiers can't carry them. - Framework-generated table names — tooling that suffixes an environment or stage onto the table name (e.g.
Todo-dev) is the classic way a dash gets in without you choosing it. - Querying an index without quotes — the
"table"."index"form needs double quotes around both parts. - Single quotes instead of double —
FROM 'my-table'fails too: single quotes denote a string literal in PartiQL, not a name.
How to fix it
Double-quote the table name:
SELECT * FROM "users-prod" WHERE pk = 'USER#42'Double-quote both parts when querying an index:
SELECT * FROM "users-prod"."email-index" WHERE email = 'ada@example.com'Keep single quotes for string values only — names in double quotes, values in single quotes. Mixing them up produces exactly this class of parse error.
Quote defensively in generated statements — if your code interpolates table names into PartiQL, always emit them double-quoted; it's valid even when the name wouldn't strictly need it.
Prefer native Query when possible. A
Query/Scanrequest sidesteps PartiQL identifier rules entirely for simple reads.
Run it in DynoTable
DynoTable's PartiQL editor double-quotes table and index names automatically — run SELECT * FROM "my-table" with inline diagnostics before you paste the statement into SDK code. Open the table with ⌘K to confirm the exact table name (including dashes) from the sidebar.
When PartiQL parsing keeps failing, switch to the Query Builder for the equivalent native request. Profile switching (⌘P) and Test Connection on Settings → Profiles keep the statement pointed at the right table. See Connect to AWS and Install.
Sources
- PartiQL select statements for DynamoDB (verified 2026-07-13)
- Supported data types and naming rules (verified 2026-07-13)
Reproduce it
A PartiQL statement whose FROM source is not a table name. The parser rejects it before it ever looks for a table, so this reproduces on any endpoint:
await client.send(new ExecuteStatementCommand({Statement: 'SELECT * FROM 123'}));Real output:
ValidationException: Unexpected from source
HTTP 400Contrast it with an unquoted but otherwise valid name: SELECT * FROM repro parses fine and fails later with ResourceNotFoundException if no such table exists. Unexpected from source is strictly a parse failure, so read it as a syntax signal, not a missing-table one.
Related errors
- DuplicateItemException — PartiQL
INSERTon an existing key. - ValidationException — the parent exception class.
- Learn: PartiQL examples · SQL for DynamoDB
References
- PartiQL select statements for DynamoDB — Amazon DynamoDB Developer Guide
- Supported data types and naming rules in Amazon DynamoDB — Amazon DynamoDB Developer Guide
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Last verified 2026-07-13 against the official AWS documentation linked above.
Reproduced 2026-07-26 against DynamoDB Local 2.x with AWS SDK for JavaScript v3.1095.0 — the output above is verbatim.