ValidationException: Inesperado de la fuente

TL;DR: el nombre de la tabla en su cláusula PartiQL FROM contiene caracteres que el analizador no aceptará solos, generalmente un guión. Escriba el nombre entre comillas dobles (SELECT * FROM "my-table"). Las comillas simples no funcionan: en PartiQL significan una cadena literal, no un identificador.

Qué significa

ValidationException: Unexpected from source

El parser de PartiQL lee FROM my-table como el identificador my seguido de tokens inesperados — el guion no es válido dentro de un identificador sin comillas. Los nombres de tabla de DynamoDB pueden contener legalmente -, . y _, así que un nombre de tabla perfectamente válido puede seguir siendo imparseable en PartiQL hasta que se pone entre comillas. Lo mismo se aplica a los nombres que colisionan con palabras clave de PartiQL.

Por qué ocurre

  • El nombre de tabla contiene un guion o un puntousers-prod, app.events. Los identificadores sin comillas no pueden llevarlos.
  • Nombres de tabla generados por frameworks — el tooling que añade como sufijo un entorno o una etapa al nombre de la tabla (p. ej. Todo-dev) es la forma clásica en que se cuela un guion sin que lo elijas.
  • Consultar un índice sin comillas — la forma "table"."index" necesita comillas dobles alrededor de ambas partes.
  • Comillas simples en lugar de doblesFROM 'my-table' también falla: las comillas simples denotan un literal de cadena en PartiQL, no un nombre.

Cómo solucionarlo

  1. Pon el nombre de tabla entre comillas dobles:

    SELECT * FROM "users-prod" WHERE pk = 'USER#42'
  2. Pon ambas partes entre comillas dobles al consultar un índice:

    SELECT * FROM "users-prod"."email-index" WHERE email = 'ada@example.com'
  3. Reserva las comillas simples solo para los valores de cadena — los nombres entre comillas dobles, los valores entre comillas simples. Confundirlos produce exactamente esta clase de error de parseo.

  4. Pon comillas de forma defensiva en las sentencias generadas — si tu código interpola nombres de tabla en PartiQL, emítelos siempre entre comillas dobles; es válido incluso cuando el nombre no lo necesitaría estrictamente.

  5. Prefiere el Query nativo cuando puedas. Una petición Query/Scan esquiva por completo las reglas de identificadores de PartiQL para lecturas sencillas.

Ejecútalo en DynoTable

El editor de PartiQL de DynoTable pone comillas dobles a los nombres de tabla e índice automáticamente — ejecuta SELECT * FROM "my-table" con diagnósticos en línea antes de pegar la sentencia en el código del SDK. Abre la tabla con ⌘K para confirmar el nombre exacto de la tabla (guiones incluidos) desde la barra lateral.

Cuando el parseo de PartiQL sigue fallando, cambia al Query Builder para la petición nativa equivalente. El cambio de perfil (⌘P) y Test Connection en Settings → Profiles mantienen la sentencia apuntando a la tabla correcta. Consulta Conectar con AWS e Instalación.

Fuentes

Reproducirlo

Una sentencia PartiQL cuya fuente FROM no es un nombre de tabla. El analizador la rechaza antes siquiera de buscar una tabla, así que esto se reproduce contra cualquier endpoint:

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

Salida real:

ValidationException: Unexpected from source
HTTP 400

Compáralo con un nombre sin comillas pero por lo demás válido: SELECT * FROM repro se analiza bien y falla más tarde con ResourceNotFoundException si no existe esa tabla. Unexpected from source es estrictamente un fallo de análisis sintáctico, así que léelo como una señal de sintaxis, no de tabla inexistente.

Errores relacionados

Referencias

Verificado por última vez el 2026-07-13 contra la documentación oficial de AWS enlazada arriba.

Reproducido el 2026-07-26 contra DynamoDB Local 2.x con AWS SDK for JavaScript v3.1095.0 — la salida de arriba es literal.

Trabaja con DynamoDB sin la Consola

Un cliente de escritorio rápido para DynamoDB que ejecuta el SQL real que DynamoDB no puede — JOINs, GROUP BY, agregaciones — con edición visual y un agente de IA con tus propias claves de Bedrock.

Prueba gratuita de 30 días, sin tarjeta — después, el plan Free sin límite de tiempo.