From c7270f58ec82b3a80df1ff6252c4f5c6bc09296d Mon Sep 17 00:00:00 2001 From: Yasmin Zhamborova Date: Mon, 22 Jun 2026 14:50:17 +0200 Subject: [PATCH 1/2] Capture Claude failure diagnostics --- docker/server-pipeline.sh | 40 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/docker/server-pipeline.sh b/docker/server-pipeline.sh index 098652b..e80d9f2 100644 --- a/docker/server-pipeline.sh +++ b/docker/server-pipeline.sh @@ -63,6 +63,9 @@ cd "${WORKSPACE}" mkdir -p "$(dirname "${SUMMARY_PATH}")" CLAUDE_STREAM_FILE=$(mktemp) +CLAUDE_STDERR_FILE=$(mktemp) +CLAUDE_DIAGNOSTICS_FILE=$(mktemp) +trap 'rm -f "${CLAUDE_STREAM_FILE:-}" "${CLAUDE_STDERR_FILE:-}" "${CLAUDE_DIAGNOSTICS_FILE:-}"' EXIT RUN_STARTED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ) echo "==> Running configure-codacy-cloud" @@ -71,6 +74,7 @@ claude -p "/configure-codacy-cloud" \ --output-format stream-json \ --verbose \ --include-partial-messages \ + 2> >(tee "${CLAUDE_STDERR_FILE}" >&2) \ | tee "${CLAUDE_STREAM_FILE}" \ | jq --unbuffered -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text' SKILL_EXIT=${PIPESTATUS[0]} @@ -97,14 +101,46 @@ RUN_META=$(jq -rsc \ sessionId: (.session_id // "") } ' "${CLAUDE_STREAM_FILE}") -rm -f "${CLAUDE_STREAM_FILE}" + +if ! jq -sc --rawfile stderr "${CLAUDE_STDERR_FILE}" ' + { + stderr: ($stderr | split("\n") | map(select(length > 0)) | .[-40:]), + resultEvents: [ .[] | select(.type == "result") ], + errorEvents: [ + .[] + | select( + .type == "error" + or ((.type == "system" or .type == "assistant") and ((.subtype? // "") | test("error|fail"; "i"))) + ) + ], + nonTextEvents: [ + .[] + | select(.type != "stream_event" or .event.delta.type? != "text_delta") + ][-20:] + } +' "${CLAUDE_STREAM_FILE}" > "${CLAUDE_DIAGNOSTICS_FILE}"; then + printf '{"diagnosticError":"failed to parse Claude stream output"}\n' > "${CLAUDE_DIAGNOSTICS_FILE}" +fi + +if [[ ${SKILL_EXIT} -ne 0 ]]; then + echo "ERROR: configure-codacy-cloud exited with code ${SKILL_EXIT}; Claude diagnostics follow" >&2 + jq '.' "${CLAUDE_DIAGNOSTICS_FILE}" >&2 || cat "${CLAUDE_DIAGNOSTICS_FILE}" >&2 +fi if [[ ! -f "${SUMMARY_PATH}" ]]; then echo "==> Skill did not produce ${SUMMARY_PATH}, writing fallback summary" if [[ ${SKILL_EXIT} -eq 0 ]]; then printf '%s\n' '{"status":"completed","note":"skill exited 0 but did not write a summary"}' > "${SUMMARY_PATH}" else - printf '{"status":"failed","exitCode":%d,"reason":"skill exited non-zero without writing a summary"}\n' "${SKILL_EXIT}" > "${SUMMARY_PATH}" + jq -n \ + --argjson exitCode "${SKILL_EXIT}" \ + --slurpfile diagnostics "${CLAUDE_DIAGNOSTICS_FILE}" \ + '{ + status: "failed", + exitCode: $exitCode, + reason: "skill exited non-zero without writing a summary", + diagnostics: ($diagnostics[0] // {}) + }' > "${SUMMARY_PATH}" fi fi From a8680875a6683ea22c7f41a64e918c23eff8dbfb Mon Sep 17 00:00:00 2001 From: zhamborova <47396369+zhamborova@users.noreply.github.com> Date: Mon, 22 Jun 2026 14:57:01 +0200 Subject: [PATCH 2/2] Update docker/server-pipeline.sh Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- docker/server-pipeline.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/server-pipeline.sh b/docker/server-pipeline.sh index e80d9f2..ac19240 100644 --- a/docker/server-pipeline.sh +++ b/docker/server-pipeline.sh @@ -74,10 +74,11 @@ claude -p "/configure-codacy-cloud" \ --output-format stream-json \ --verbose \ --include-partial-messages \ - 2> >(tee "${CLAUDE_STDERR_FILE}" >&2) \ + 2> "${CLAUDE_STDERR_FILE}" \ | tee "${CLAUDE_STREAM_FILE}" \ | jq --unbuffered -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text' SKILL_EXIT=${PIPESTATUS[0]} +cat "${CLAUDE_STDERR_FILE}" >&2 RUN_FINISHED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ) echo