Skip to content

Commit 56e82d7

Browse files
committed
fix(parser): scope opencode exit failures to bash
1 parent 03ade78 commit 56e82d7

3 files changed

Lines changed: 16 additions & 4 deletions

File tree

docs/internal/session-format-sources.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ Grok section and remove the explicit registry exception in the coverage test.
244244
failure signal. The tool's own output text carries no `exit status N`
245245
marker, and the shell is `COMSPEC`/`cmd.exe` on Windows, so text-pattern
246246
matching alone misses these failures on every platform. Agentsview treats a
247-
non-zero `state.metadata.exit` on any tool part as a failure and attaches an
248-
errored result event. Only `bash` parts record `exit`; other tools omit the
247+
non-zero `state.metadata.exit` on a `bash` tool part as a failure and attaches
248+
an errored result event. Only `bash` parts record `exit`; other tools omit the
249249
key. Verified 2026-07-24 against a live `opencode.db` where all 24 bash
250250
parts with `exit` in `{1, 127, 128}` had output text without an
251251
`exit status` marker, and the 81 successful parts recorded `exit=0`. Known

internal/parser/opencode.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ func extractOpenCodeToolCall(data, cwd string) ParsedToolCall {
10131013
// state metadata. On Windows the output text carries
10141014
// no "exit status N" marker, so metadata.exit is the
10151015
// only reliable failure signal.
1016-
if len(state.Metadata) > 0 {
1016+
if d.ToolName == "bash" && len(state.Metadata) > 0 {
10171017
var m openCodeToolMetadata
10181018
if err := json.Unmarshal(state.Metadata, &m); err == nil && m.Exit > 0 {
10191019
isFailure = true

internal/parser/opencode_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,34 +936,46 @@ func TestParseOpenCodeDB_InvalidToolCall(t *testing.T) {
936936
func TestParseOpenCodeDB_BashExitFailure(t *testing.T) {
937937
tests := []struct {
938938
name string
939+
tool string
939940
state string
940941
wantErrored bool
941942
}{
942943
{
943944
name: "non-zero exit without exit-status text",
945+
tool: "bash",
944946
state: `{"input":{"command":"build"},"output":"error: command failed","metadata":{"exit":1}}`,
945947
wantErrored: true,
946948
},
947949
{
948950
name: "non-zero exit with empty output",
951+
tool: "bash",
949952
state: `{"input":{"command":"build"},"output":"","metadata":{"exit":127}}`,
950953
wantErrored: true,
951954
},
952955
{
953956
name: "zero exit is not a failure",
957+
tool: "bash",
954958
state: `{"input":{"command":"build"},"output":"ok","metadata":{"exit":0}}`,
955959
wantErrored: false,
956960
},
957961
{
958962
name: "metadata without an exit key is not a failure",
963+
tool: "bash",
959964
state: `{"input":{"command":"build"},"output":"ok","metadata":{"truncated":false}}`,
960965
wantErrored: false,
961966
},
962967
{
963968
name: "no metadata is not a failure",
969+
tool: "bash",
964970
state: `{"input":{"command":"build"},"output":"ok"}`,
965971
wantErrored: false,
966972
},
973+
{
974+
name: "non-bash metadata exit is not a failure",
975+
tool: "mcp_lookup",
976+
state: `{"input":{"query":"exit routes"},"output":"route 1","metadata":{"exit":1}}`,
977+
wantErrored: false,
978+
},
967979
}
968980

969981
for _, tt := range tests {
@@ -979,7 +991,7 @@ func TestParseOpenCodeDB_BashExitFailure(t *testing.T) {
979991

980992
seeder.AddMessage("msg_a", "ses_bexit", 1700000010000, 1700000010000, `{"role":"assistant"}`)
981993
seeder.AddPart("prt_t", "msg_a", "ses_bexit", 1700000010000, 1700000010000,
982-
`{"type":"tool","tool":"bash","callID":"call_exit","state":`+tt.state+`}`)
994+
`{"type":"tool","tool":"`+tt.tool+`","callID":"call_exit","state":`+tt.state+`}`)
983995

984996
sessions, err := parseOpenCodeAll(dbPath, "m")
985997
require.NoError(t, err, "ParseOpenCodeDB")

0 commit comments

Comments
 (0)