Skip to content

Fix CSV/RAW output header being application/json rather than plain/text (backport #1779 to 1.3)#11

Draft
RyanL1997 wants to merge 1 commit into
1.3from
fix/csv-raw-content-type-1.3
Draft

Fix CSV/RAW output header being application/json rather than plain/text (backport #1779 to 1.3)#11
RyanL1997 wants to merge 1 commit into
1.3from
fix/csv-raw-content-type-1.3

Conversation

@RyanL1997

Copy link
Copy Markdown
Owner

Description

Backport of #1779 to the 1.3 line.

The SQL/PPL REST handlers hardcode the response Content-Type to application/json for every format, including format=csv and format=raw whose bodies are plain text. Clients that trust the Content-Type header — notably the OpenSearch Dashboards legacy client used by Query Workbench — then try to JSON.parse the CSV/raw body, which throws a serialization error and surfaces to the user as an HTTP 400 even though the returned data is correct.

Change

  • Add ResponseFormatter#contentType().
  • FlatResponseFormatter (CSV/RAW) returns plain/text; charset=UTF-8; JsonResponseFormatter (JDBC/JSON) returns application/json; charset=UTF-8.
  • Thread formatter.contentType() through RestSQLQueryAction#sendResponse so each format returns the correct header. JDBC/JSON responses are unchanged.

Verification (local OpenSearch 1.3.2)

Request Before After
POST /_plugins/_sql?format=csv 200 application/json 200 plain/text
POST /_plugins/_sql?format=raw 200 application/json 200 plain/text
default (JDBC) / format=json application/json application/json (unchanged)

Full loop: repointed a local OpenSearch Dashboards Query Workbench at the patched cluster — the Download and verify CSV and Download and verify Text Cypress tests now pass (previously failed with 400).

Draft: opened against the fork's 1.3 branch for review of the diff.

Backport of opensearch-project#1779 to 1.3.

The SQL/PPL REST handlers hardcode the response Content-Type to
"application/json" for every format, including format=csv and
format=raw whose bodies are plain text. Downstream clients that trust
the Content-Type header (e.g. OpenSearch Dashboards' legacy client used
by Query Workbench) then attempt to JSON-parse the CSV/raw body, which
fails and surfaces as an HTTP 400 to the user even though the data is
correct.

Add ResponseFormatter#contentType(): FlatResponseFormatter (CSV/RAW)
returns "plain/text; charset=UTF-8" and JsonResponseFormatter (JDBC/
JSON) returns "application/json; charset=UTF-8". Thread the formatter's
content type through RestSQLQueryAction so each format returns the
correct header. JDBC/JSON responses are unchanged.

Verified on a local OpenSearch 1.3.2 cluster: format=csv/raw now return
plain/text (200) and the Query Workbench CSV/Text download tests pass
(previously 400).
Repository owner deleted a comment from ryan-gh-bot Jul 10, 2026
Repository owner deleted a comment from ryan-gh-bot Jul 10, 2026
@RyanL1997

Copy link
Copy Markdown
Owner Author

@ryan-gh-bot can you take a look the ci failures on this branch - I know this is an old branch and some ci task may be failed, but can you double confirm it is not related to any of my change?

@ryan-gh-bot

Copy link
Copy Markdown

Working on /@triage (invoked by @RyanL1997) — posting result when done.

@ryan-gh-bot

Copy link
Copy Markdown

[Note] CI failures are pre-existing on the 1.3 branch and unrelated to this PR

Confirmed the failing checks are not caused by the changes in this backport. They are pre-existing GitHub Actions infrastructure failures on the 1.3 branch: the workflow definitions reference deprecated action versions (actions/checkout@v1, actions/setup-java@v1, actions/setup-python@v2) whose Node 12/16 runtimes GitHub no longer supports, so the runner rejects the workflow before any step executes.

Environment

Analysis

Three independent signals show these failures are branch-infrastructure issues, not something this PR introduced:

  1. The PR touches no CI files. The diff is 4 Java files in legacy/ and protocol/. No workflow YAML is modified.

  2. The base commit fails identically. 6116c33 (current tip of 1.3, no PR changes) reports the same failing set: build, build (8), build (11), build (14), build (3.8), plus queued mac/windows ODBC jobs.

  3. Jobs fail in 1-2 seconds with steps: []. The GitHub Actions API shows all failing jobs completed with an empty steps array before any step ran — classic signature of a runner refusing to start the workflow because it pins an unsupported action major version.

Looking at the workflows on this branch:

Evidence

# 1. PR file scope — only Java files, no workflows
$ git diff --name-only target/1.3...target/fix/csv-raw-content-type-1.3
legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSQLQueryAction.java
protocol/src/main/java/org/opensearch/sql/protocol/response/format/FlatResponseFormatter.java
protocol/src/main/java/org/opensearch/sql/protocol/response/format/JsonResponseFormatter.java
protocol/src/main/java/org/opensearch/sql/protocol/response/format/ResponseFormatter.java
# 2. Failing check runs on PR head b41d2f6 — all completed in 1-2 seconds
build (3.8)   failure   started 04:38:24Z  completed 04:38:26Z  (2s)
build         failure   started 04:38:24Z  completed 04:38:25Z  (1s)
build (14)    failure   started 04:38:24Z  completed 04:38:25Z  (1s)
build (11)    failure   started 04:38:24Z  completed 04:38:25Z  (1s)
build (8)     cancelled started 04:38:24Z  completed 04:38:25Z  (1s)
# 3. Base commit 6116c33 (tip of 1.3, no PR changes) — identical failure set
build (3.8)   failure
build (14)    failure
build         failure  (x2 workflows)
build (11)    cancelled
build (8)     failure
# 4. Empty steps array in the failed jobs (from Actions API)
$ curl .../actions/runs/29069507501/jobs | jq '.jobs[] | {name, conclusion, steps}'
{ "name": "build (11)", "conclusion": "failure", "steps": [] }
{ "name": "build (14)", "conclusion": "failure", "steps": [] }
{ "name": "build (8)",  "conclusion": "cancelled", "steps": [] }

Next steps

  • Safe to disregard these CI failures for the purpose of reviewing the diff — this backport does not regress CI. The workflows would need to be bumped to modern action versions (actions/checkout@v4, actions/setup-java@v4, actions/setup-python@v5, and a supported JDK matrix) before the 1.3 branch can produce green builds again.
  • Unverified suggestion: if you want to confirm the Java changes actually compile on 1.3, the fastest local check is ./gradlew :legacy:compileJava :protocol:compileJava -Dopensearch.version=1.3.20-SNAPSHOT from a checkout of b41d2f6. Happy to run that under a /reproduce follow-up if useful.

Automated response from @ryan-gh-bot (maintainer-triggered agent). About this agent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants