From 115091722930ec1c42352294977d5826d8abaaa0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:02:23 +0000 Subject: [PATCH 1/3] Surface Codex JSONL error events in step-summary rendering Codex CLI's JSONL log format emits item.completed events with item.type "error" (e.g. model-fallback warnings), but parseCodexJsonl() silently dropped any item type it didn't recognize, so these messages never reached the rendered step summary or logEntries. Found while verifying the rendering pipeline against real output from workflow run 33729471900 (Issue Monster, codex engine): the log contained a "Model metadata ... not found" error item that was completely absent from the generated markdown. --- actions/setup/js/parse_codex_log.cjs | 39 +++++++++++++++++++++------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/actions/setup/js/parse_codex_log.cjs b/actions/setup/js/parse_codex_log.cjs index 98ccf5aa102..1945077eaf2 100644 --- a/actions/setup/js/parse_codex_log.cjs +++ b/actions/setup/js/parse_codex_log.cjs @@ -409,14 +409,31 @@ function parseCodexJsonl(logContent) { }); break; } + case "error": { + const message = typeof item.message === "string" ? item.message : JSON.stringify(item); + if (message.trim()) { + parsedData.push({ type: "error", content: message }); + } + break; + } default: break; } } + const errorMessages = parsedData.filter(item => item.type === "error").map(item => item.content); + // Build markdown so the parser returns a truthy result and core.info has a // readable fallback. The step summary itself is rendered from logEntries. - let markdown = "
\nReasoning\n\n"; + let markdown = ""; + if (errorMessages.length > 0) { + markdown += "
\nErrors\n\n"; + for (const message of errorMessages) { + markdown += `> ${message}\n\n`; + } + markdown += "
\n\n"; + } + markdown += "
\nReasoning\n\n"; for (const item of parsedData) { if (item.type === "text") { markdown += `${item.content}\n\n`; @@ -456,17 +473,21 @@ function parseCodexJsonl(logContent) { model: model || undefined, }); - // Surface token usage and turn count via a result entry so Statistics and the - // OTEL telemetry enrichment (agent-stdio.log result line) are populated. - if (usage) { + // Surface token usage, turn count, and error messages via a result entry so + // Statistics, the Information section's Errors list, and the OTEL telemetry + // enrichment (agent-stdio.log result line) are populated. + if (usage || errorMessages.length > 0) { logEntries.push({ type: "result", num_turns: turnCount > 0 ? turnCount : undefined, - usage: { - input_tokens: typeof usage.input_tokens === "number" ? usage.input_tokens : undefined, - output_tokens: typeof usage.output_tokens === "number" ? usage.output_tokens : undefined, - cache_read_input_tokens: typeof usage.cached_input_tokens === "number" ? usage.cached_input_tokens : undefined, - }, + usage: usage + ? { + input_tokens: typeof usage.input_tokens === "number" ? usage.input_tokens : undefined, + output_tokens: typeof usage.output_tokens === "number" ? usage.output_tokens : undefined, + cache_read_input_tokens: typeof usage.cached_input_tokens === "number" ? usage.cached_input_tokens : undefined, + } + : undefined, + errors: errorMessages.length > 0 ? errorMessages : undefined, }); } From 15e4b583fdecb75dd80e1277a6c441e3956baf3a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 3 Sep 2026 14:51:58 +0000 Subject: [PATCH 2/3] Preserve Codex errors in rendered summaries Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/log_parser_format.cjs | 6 ++++++ actions/setup/js/parse_codex_log.test.cjs | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/actions/setup/js/log_parser_format.cjs b/actions/setup/js/log_parser_format.cjs index 99384688ced..cf68ccbed05 100644 --- a/actions/setup/js/log_parser_format.cjs +++ b/actions/setup/js/log_parser_format.cjs @@ -585,6 +585,12 @@ function createLogParserFormatters(deps) { if (lastEntry?.total_cost_usd) { lines.push(` Cost: $${lastEntry.total_cost_usd.toFixed(4)}`); } + if (lastEntry?.errors && Array.isArray(lastEntry.errors) && lastEntry.errors.length > 0) { + lines.push(" Errors:"); + for (const error of lastEntry.errors) { + lines.push(` ${error}`); + } + } } function generateSummaryLines(logEntries) { diff --git a/actions/setup/js/parse_codex_log.test.cjs b/actions/setup/js/parse_codex_log.test.cjs index 74b0f3c37ed..df0fc4083d0 100644 --- a/actions/setup/js/parse_codex_log.test.cjs +++ b/actions/setup/js/parse_codex_log.test.cjs @@ -9,6 +9,7 @@ describe("parse_codex_log.cjs", () => { let estimateTokens; let formatDuration; let extractMCPInitialization; + let generateCopilotCliStyleSummary; beforeEach(async () => { // Mock core actions methods @@ -38,6 +39,7 @@ describe("parse_codex_log.cjs", () => { truncateString = sharedModule.truncateString; estimateTokens = sharedModule.estimateTokens; formatDuration = sharedModule.formatDuration; + generateCopilotCliStyleSummary = sharedModule.generateCopilotCliStyleSummary; }); describe("parseCodexLog function", () => { @@ -833,5 +835,18 @@ ERROR: This user's access to o4-mini has been temporarily limited`; expect(result.markdown).toContain("Reviewed the issue"); expect(result.markdown).toContain("Total Tokens Used:"); }); + + it("surfaces item errors in the result and rendered step summary without usage", () => { + const errorMessage = "Model metadata unavailable; using fallback metadata."; + const errorOnlyLog = ['{"type":"thread.started","thread_id":"019ef8cb"}', `{"type":"item.completed","item":{"id":"item_0","type":"error","message":"${errorMessage}"}}`, '{"type":"turn.completed"}'].join("\n"); + + const result = parseCodexLog(errorOnlyLog); + const resultEntry = result.logEntries.find(e => e.type === "session.result"); + + expect(resultEntry?.data?.errors).toEqual([errorMessage]); + expect(generateCopilotCliStyleSummary(result.logEntries)).toContain(errorMessage); + expect(result.markdown).toContain("Errors"); + expect(result.markdown).toContain(errorMessage); + }); }); }); From 5f24e9de8e7a397b6252ebed36400b9349b74f30 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 3 Sep 2026 15:02:31 +0000 Subject: [PATCH 3/3] Trim Codex error messages Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/parse_codex_log.cjs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/actions/setup/js/parse_codex_log.cjs b/actions/setup/js/parse_codex_log.cjs index 1945077eaf2..8b2c532c344 100644 --- a/actions/setup/js/parse_codex_log.cjs +++ b/actions/setup/js/parse_codex_log.cjs @@ -410,8 +410,9 @@ function parseCodexJsonl(logContent) { break; } case "error": { - const message = typeof item.message === "string" ? item.message : JSON.stringify(item); - if (message.trim()) { + const rawMessage = typeof item.message === "string" ? item.message : JSON.stringify(item); + const message = rawMessage.trim(); + if (message) { parsedData.push({ type: "error", content: message }); } break;