fix(explore): avoid panic when printing an empty result set - #68
Conversation
`getSelectedContent` indexed `rowData` at the table cursor without checking
that a row exists. An empty array or object builds a TableView with no rows,
so pressing "p" on one crashed the CLI with an index out of range panic.
This is reachable whenever a list endpoint returns no results, since
`ExploreJSONStream` marshals zero items into `[]` and builds the table from
that, e.g. `openai files list --format explore` on an account with no files.
`navigateForward` already guards the same empty `rowData` case; this applies
the equivalent check to the print path and falls back to the container that
the view is displaying, so "p" prints `[]` or `{}` instead of panicking.
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
saioai
left a comment
There was a problem hiding this comment.
i reproduced the crash on the old code when pressing p on an empty [] or {}, and this change prints the empty result instead. the new test passed 100 runs. the jsonview race tests, internal tests, repo compilation, vet, module verification, formatting, and diff checks passed locally too. github checks still need to run before merge.
Castiron custom code✅ No new custom-code files detected. 5 mixed files remain; 0 existing customizations changed. Compared 5 existing customizations unchanged
A changed generated baseline means this report cannot reliably identify which handwritten lines changed. Inspect the custom-code diffDownload the exact patch produced by this run (requires repository access): gh run download 34909096412 --repo openai/openai-cli \
--name castiron-custom-code-34909096412-1 --dir /tmp/castiron-custom-code-34909096412-1
git apply --stat /tmp/castiron-custom-code-34909096412-1/custom-code.patch
cat /tmp/castiron-custom-code-34909096412-1/custom-code.patchOr reproduce it from an SDK checkout containing the vendored reporter: git fetch --no-tags origin 552840e37ec4b0156ec498159e3bf03804ee643d 72e912e43bed9f24717a2aa96ae594abb1a95eaf
python3 scripts/castiron/custom_code_report.py report \
--base 552840e37ec4b0156ec498159e3bf03804ee643d \
--head 72e912e43bed9f24717a2aa96ae594abb1a95eaf --fetch --require-head-hash --public \
--out /tmp/castiron-custom-code-72e912e43bed
cat /tmp/castiron-custom-code-72e912e43bed/custom-code.patchThis is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR. |
Automated Release PR --- ## [1.16.0](openai/openai-cli@v1.15.0...v1.16.0) (2026-09-22) ### Features * **api:** add external storage and safety case commands ([openai#229](openai#229)) ([c30c961](openai@c30c961)) * **api:** add prompt-cache prewarming ([openai#196](openai#196)) ([9032f58](openai@9032f58)) * **api:** add response transformation hooks ([openai#223](openai#223)) ([8de34a7](openai@8de34a7)) * **api:** add webhook endpoint management ([openai#201](openai#201)) ([dea465a](openai@dea465a)) * **cli:** support custom request headers ([openai#190](openai#190)) ([07e3ed9](openai@07e3ed9)) ### Bug Fixes * **apiform:** preserve float32 precision in comma arrays ([openai#78](openai#78)) ([774612f](openai@774612f)) * **apiform:** strip path components from upload filenames ([openai#120](openai#120)) ([a92e143](openai@a92e143)) * **apiform:** support primitive pointers in comma arrays ([openai#119](openai#119)) ([9d146cd](openai@9d146cd)) * **apiquery:** preserve narrow numeric parameters ([openai#76](openai#76)) ([b152780](openai@b152780)) * **apiquery:** reject complex elements in comma arrays ([openai#118](openai#118)) ([46faf2c](openai@46faf2c)) * **apiquery:** reject non-string map keys ([openai#88](openai#88)) ([687a097](openai@687a097)) * **autocomplete:** omit hidden flags from suggestions ([openai#122](openai#122)) ([137d59b](openai@137d59b)) * **cmd:** include backslash in path detection for @ file references ([openai#38](openai#38)) ([f984eb1](openai@f984eb1)) * **debug:** redact sensitive response headers ([openai#32](openai#32)) ([ee62f85](openai@ee62f85)) * **explore:** avoid panic when printing an empty result set ([openai#68](openai#68)) ([f74838c](openai@f74838c)) * install Linux package binaries under /usr/bin ([openai#34](openai#34)) ([ac4e7cb](openai@ac4e7cb)) * **jsonview:** avoid width underflow in static string rendering ([openai#117](openai#117)) ([cbdf265](openai@cbdf265)) * **jsonview:** preserve literal object keys in pretty output and explorer ([openai#143](openai#143)) ([25664bf](openai@25664bf)) * omit redirect destinations from multipart upload errors ([openai#189](openai#189)) ([642d511](openai@642d511)) * **output:** stop pagination at max items ([openai#43](openai#43)) ([552840e](openai@552840e)) * **requestflag:** preserve JSON numbers written in exponent form ([openai#195](openai#195)) ([20db45e](openai@20db45e)) ### Chores * **api:** clarify Live SIP call help ([openai#193](openai#193)) ([79435c4](openai@79435c4)) * **api:** document MCP connector deprecation ([openai#202](openai#202)) ([1d4e76c](openai@1d4e76c)) * **api:** update image request examples ([openai#197](openai#197)) ([4b75e9b](openai@4b75e9b)) * **deps:** bump the codeql group across 1 directory with 2 updates ([openai#161](openai#161)) ([97734f3](openai@97734f3)) * **deps:** bump the codeql group across 1 directory with 2 updates ([openai#224](openai#224)) ([0713595](openai@0713595)) * **deps:** bump the go-minor-and-patch group across 1 directory with 2 updates ([openai#144](openai#144)) ([aa1158d](openai@aa1158d)) * **deps:** update openai-go to v3.61.0 ([openai#184](openai#184)) ([de52b2e](openai@de52b2e)) * **deps:** update openai-go to v3.63.0 ([openai#198](openai#198)) ([3f2c883](openai@3f2c883)) * **deps:** update openai-go to v3.63.1 ([openai#204](openai#204)) ([eb415e5](openai@eb415e5)) * **deps:** update openai-go to v3.64.0 ([openai#206](openai#206)) ([0169bff](openai@0169bff)) * **deps:** update openai-go to v3.64.2 ([openai#225](openai#225)) ([a7859e5](openai@a7859e5)) ### Documentation * correct bootstrap dependency check description ([openai#181](openai#181)) ([4aa657c](openai@4aa657c)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: openai-sdks[bot] <284451331+openai-sdks[bot]@users.noreply.github.com> Co-authored-by: saioai <vguvvala@openai.com>
Summary
Pressing
p("print and exit") in the--format exploreviewer panics when the result set is empty.getSelectedContentindexesrowDataat the table cursor without checking that a row exists:https://github.com/openai/openai-cli/blob/7d87ee2/internal/jsonview/explorer.go#L423-L434
An empty array or object builds a
TableViewwith no rows,table.Cursor()returns0, and the index panics.navigateForwardalready guards this exact case (added inTestNavigateForward_EmptyRowData), so this looks like the same oversight in the sibling path rather than an intended difference.How it is reached
Any list endpoint that returns no results.
ExploreJSONStreamcollects zero items,marshalItemsToJSONArrayreturns[], andnewTableViewbuilds a table with no rows:https://github.com/openai/openai-cli/blob/7d87ee2/internal/jsonview/explorer.go#L331-L349
So on an account with no files:
then press
p, and the CLI exits with a runtime panic and a Go stack trace instead of printing anything. The same applies to a top level empty object viaExploreJSON.Every other key binding (
↑,↓,←,→,r,q) already handles the empty view fine.pis the only one that crashes.Reproduction
Reverting just the one line change and running the test added here:
With the fix applied, both cases pass.
Fix
Bounds check the cursor before indexing, and fall back to the container the view is already displaying, so
pprints[]or{}. That matches the existing fallback for non table views a few lines above, which returnsGetData().Raw.The test drives
Updatewith the actualpkey message rather than calling the unexported helper directly, so it covers the real key binding path and asserts the printed output, not just the absence of a panic.Notes
go build ./...andgo vet ./...are clean;go test ./internal/...passes apart frominternal/autocomplete, which fails identically on an unmodified checkout in my environment (it shells out to/bin/bashand I am on Windows), so it is unrelated to this change.