{"record":{"id":"aa9b4a5690b88639","repo":"gitbutlerapp/gitbutler","slug":"the-updated-review-was-missing-from-the-response","errorCode":null,"errorMessage":"The updated review was missing from the response.","messagePattern":"The updated review was missing from the response\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/but-mcp-app/src/ReviewApp.tsx","lineNumber":404,"sourceCode":"\tconst connectedApp = app;\n\tconst currentView = view;\n\tconst canCallTools = connectedApp.getHostCapabilities()?.serverTools !== undefined;\n\n\tasync function markReady(review: ReviewCardData) {\n\t\tsetPendingReview(review.number);\n\t\tsetActionError(null);\n\t\ttry {\n\t\t\tconst result = await connectedApp.callServerTool({\n\t\t\t\tname: \"gitbutler_mark_review_ready\",\n\t\t\t\targuments: {\n\t\t\t\t\trepository: currentView.repository.path,\n\t\t\t\t\treviewNumber: review.number,\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (result.isError) throw new Error(textFromToolResult(result));\n\t\t\tconst updatedView = reviewViewFromToolResult(result);\n\t\t\tconst updatedReview = updatedView?.reviews[0];\n\t\t\tif (!updatedReview) throw new Error(\"The updated review was missing from the response.\");\n\t\t\tsetView((current) =>\n\t\t\t\tcurrent === null || updatedView === null ? current : mergeReviewViews(current, updatedView),\n\t\t\t);\n\t\t} catch (actionCause) {\n\t\t\tsetActionError(\n\t\t\t\tactionCause instanceof Error ? actionCause.message : \"Could not mark the review ready.\",\n\t\t\t);\n\t\t} finally {\n\t\t\tsetPendingReview(null);\n\t\t}\n\t}\n\n\tasync function openReview(review: ReviewCardData) {\n\t\tsetActionError(null);\n\t\ttry {\n\t\t\tawait connectedApp.openLink({ url: review.url });\n\t\t} catch (actionCause) {\n\t\t\tsetActionError(","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/packages/but-mcp-app/src/ReviewApp.tsx#L386-L422","documentation":"Thrown at ReviewApp.tsx:404 after gitbutler_mark_review_ready returned success (no isError) and reviewViewFromToolResult accepted the structuredContent, but the reviews array is missing or empty (updatedView?.reviews[0] is undefined). The tool acknowledged success without echoing the updated review, so the UI has nothing to merge and reports the error via setActionError.","triggerScenarios":"The tool's success payload carries an empty reviews array or a renamed field; version skew where mark_ready returns a bare {ok:true} without the review echo; the updated review legitimately fell outside a UI filter (e.g. it left the draft scope after becoming ready).","commonSituations":"UI filtering drafts: marking ready removes the review from the filtered result set; tool/UI version mismatch after a partial upgrade.","solutions":["Update the but CLI/desktop so mark_ready echoes the updated review in structuredContent.reviews","Refresh the full review list after a successful mark-ready instead of relying on the echo","Check whether a UI filter explains the empty array before treating it as a failure"],"exampleFix":"// before\nconst updatedReview = updatedView?.reviews[0];\nif (!updatedReview) throw new Error(\"The updated review was missing from the response.\");\n\n// after — fall back to a full list refresh when the echo is absent\nif (updatedView?.reviews[0]) {\n\tsetView((current) => (current === null ? current : mergeReviewViews(current, updatedView)));\n} else {\n\tawait refreshReviewList(); // success without echo: resync from the source\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function hasUpdatedReview(v: ReviewView | null): v is ReviewView & { reviews: [ReviewCardData, ...ReviewCardData[]] } {\n\treturn Array.isArray(v?.reviews) && v.reviews.length > 0;\n}","tryCatchPattern":"const updatedView = reviewViewFromToolResult(result);\nif (hasUpdatedReview(updatedView)) {\n\tsetView((current) => (current === null ? current : mergeReviewViews(current, updatedView)));\n} else {\n\t// success without an echo: resync from a full list refresh instead of erroring\n\tawait refreshReviewList();\n}","preventionTips":["Fall back to a full list refresh when a success response lacks the echoed entity","Watch UI filters (e.g. draft-only) that legitimately empty the result set","Keep tool and UI versions in lockstep so mark_ready echoes the updated review"],"tags":["mcp","reviews","schema-validation"],"backgroundTag":"mcp-structured-content-missing","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}