{"record":{"id":"da3797e2e81f05de","repo":"Hmbown/CodeWhale","slug":"cloud-agent-produced-an-empty-patch-refusing-to-open-a-pr","errorCode":null,"errorMessage":"Cloud agent produced an empty patch; refusing to open a PR.","messagePattern":"Cloud agent produced an empty patch; refusing to open a PR\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/tui/src/cloud_dispatch.rs","lineNumber":1752,"sourceCode":"            .to_string();\n        let patch = self.run_harness(\n            receipt,\n            &HarnessCommand {\n                argv: vec![\n                    \"git\".to_string(),\n                    \"format-patch\".to_string(),\n                    \"origin/HEAD..HEAD\".to_string(),\n                    \"--stdout\".to_string(),\n                ],\n                cwd: SANDBOX_WORKSPACE.to_string(),\n                timeout_secs: 60,\n            },\n        )?;\n        if base_branch.is_empty() || head_sha.len() < 7 {\n            bail!(\"Cloud agent produced no branch head to raise.\");\n        }\n        if patch.trim().is_empty() {\n            bail!(\"Cloud agent produced an empty patch; refusing to open a PR.\");\n        }\n        Ok(PatchReceipt {\n            base_branch,\n            head_sha,\n            summary,\n            patch,\n        })\n    }\n\n    fn teardown(&self, receipt: &SandboxReceipt) -> Result<()> {\n        let api_key = Self::api_key()?;\n        if !valid_sandbox_id(&receipt.sandbox_id) {\n            bail!(\"the sandbox id is not a usable path token\");\n        }\n        let url = Self::control_plane_url(&format!(\"sandbox/{}\", receipt.sandbox_id))?;\n        let response = Self::send_json(\n            reqwest::Method::DELETE,\n            &url,","sourceCodeStart":1734,"sourceCodeEnd":1770,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/cloud_dispatch.rs#L1734-L1770","documentation":"Thrown after the branch-head check passes but the collected patch text is whitespace-only. The sandbox has a valid base branch and head SHA, yet the diff between them is empty — the agent's commits contain no changes — so the dispatcher refuses to open an empty PR. This is a deliberate guard against publishing no-op pull requests.","triggerScenarios":"Raising a PR from a cloud-agent run where the agent created a commit with no actual diff (e.g. `git commit --allow-empty`, commits reverted to identical trees, or a merge commit only).","commonSituations":"Agent decided no change was needed but still committed; agent's edits exactly reverted prior changes; task prompt was answered with commentary only while a commit hook still created an empty commit.","solutions":["Inspect the agent's summary/transcript to confirm the task genuinely required no change; if so, discard the job instead of retrying.","Re-run the job with a clearer instruction that code changes are expected when the task is a fix or feature.","Check whether the agent's edits were made outside the git worktree (wrong cwd) — files written next to, not inside, the repo produce an empty patch.","If empty commits are intentional noise, prevent the agent from committing when there is no diff (`git diff --quiet && exit 0 || git commit ...`)."],"exampleFix":"// agent commit step: refuse empty commits\n[\"bash\", \"-lc\", \"git diff --quiet && echo 'no changes' && exit 1 || git commit -am task\"],","handlingStrategy":"validation","validationCode":"// agent-side guard: never commit an empty diff\n[\"bash\", \"-lc\", \"git diff --quiet && git diff --cached --quiet && echo NO_CHANGES || git commit -am task\"]","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"empty patch\") => {\n        // no-op job: discard, don't retry endlessly\n        mark_job_noop(job_id);\n    }\n    other => other,\n}","preventionTips":["Instruct agents explicitly that a fix/feature task must produce a non-empty diff.","Reject empty commits in the agent's commit step (`git diff --quiet` guard).","Verify the agent wrote files inside the git worktree, not an adjacent path.","Distinguish 'agent chose no change' from 'agent wrote outside the repo' by checking the transcript."],"tags":["git","cloud","pr","empty-diff"],"backgroundTag":"empty-result-set","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}