es-client: non-JSON error responses report "Body is unusable" instead of the HTTP status
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 75/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- nodejs, typescript
- Área
- backend-api-design, cli
Línea de trabajo
El error está en src/lib/es-client.ts líneas 125-132. Comience leyendo el archivo para comprender el flujo de solicitudes. La solución es leer primero el cuerpo de la respuesta como texto y luego intentar analizarlo como JSON, de manera similar a como lo manejan kibana-client.ts y cloud-client.ts. Escriba una prueba para reproducir el error usando un servidor HTTP simulado que devuelva una respuesta de error que no sea JSON, luego verifique que la corrección devuelva el código de estado y el cuerpo correctos.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
Any non-2xx response whose body is not valid JSON surfaces as Error: Body is unusable: Body has already been read, losing the status code. That is undici's TypeError — the error branch of
EsClient.request reads the body twice. Deterministic, not timing-dependent.
The usual way to hit it is a reverse proxy in front of Elasticsearch: proxy_read_timeout expiring
on a long ES|QL query returns an nginx HTML 504, and the CLI reports Body is unusable instead of
504 — pointing suspicion at the client rather than the proxy.
Root cause
src/lib/es-client.ts#L125-L132:
if (!response.ok) {
let body: unknown
try {
body = await response.json() // consumes the stream
} catch {
body = await response.text() // ← throws: body already consumed
}
throw new EsResponseError(response.status, body)
}
response.json() disturbs the body even when it rejects, so the catch branch can never read it.
Reproduction
cat > elasticrc-local.yml <<'YAML'
current_context: local
contexts:
local:
elasticsearch:
url: http://127.0.0.1:9999
auth: { api_key: ZmFrZTpmYWtl }
YAML
chmod 0600 elasticrc-local.yml
export ELASTIC_CLI_CONFIG_FILE="$PWD/elasticrc-local.yml" NO_PROXY=localhost,127.0.0.1
# stand in for "ES behind a proxy that timed out"
node -e 'require("http").createServer((q,s)=>{s.writeHead(504,{"content-type":"text/html"});s.end("<html><body>504 Gateway Time-out</body></html>")}).listen(9999,"127.0.0.1")' &
elastic es esql query --query 'FROM x | LIMIT 1' --format txt
# Error: Body is unusable: Body has already been read (exit 1)
Same for 502, 503, text/plain and empty bodies. A JSON error body works correctly
(Error: illegal_argument_exception: …). Reproduced on v0.4.0 and v0.5.0, Node v26.8.1,
Linux x86_64, against Elasticsearch 9.5.3.
Suggested fix
Read once, then parse — as kibana-client.ts#L212
and cloud-client.ts#L75
already do in this repo:
const text = await response.text()
let body: unknown
try {
body = JSON.parse(text)
} catch {
body = text
}
throw new EsResponseError(response.status, body)
EsResponseError's message should also carry the status, since a string body currently renders as
bare HTML. Happy to open a PR with tests for an HTML and an empty error body.
Context
Introduced by #281 (native-fetch EsClient); @elastic/transport handled it correctly. Present in
every release since v0.2.0 and on main today. #588 fixed the same blind-JSON.parse mistake on
the success branch of this file — this is the error branch.
- Lenguaje dominante
- TypeScript
- Estrellas
- 43
- Forks
- 24
- Merge medio
- 1 d 5 h
- PR fusionados (30 d)
- 61
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de elastic/cli
-
cloud enhancement
Dificultad 1/5 1-3 horas Aptitud para principiantes 88/100
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Todos los issues de elastic/cli
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
mksglu/context-mode#1200 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
jaegertracing/jaeger-ui#4506 ·
-
area:desktop area:ui bug platform:macos
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
anthropics/claude-code#96687 ·
-
good first issue
Dificultad 1/5 Menos de una hora Aptitud para principiantes 95/100
AOSSIE-Org/DebateAI#582 · 2 comentarios ·