{"record":{"id":"88dcf84261821c7c","repo":"paperclipai/paperclip","slug":"failed-to-compute-a-merged-git-tree-for-ssh-worksp","errorCode":null,"errorMessage":"Failed to compute a merged git tree for SSH workspace restore.","messagePattern":"Failed to compute a merged git tree for SSH workspace restore\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/ssh.ts","lineNumber":971,"sourceCode":"        throw error;\n      }\n    }\n\n    let mergedTree;\n    try {\n      mergedTree = await runLocalGit(input.localDir, [\"merge-tree\", \"--write-tree\", currentHead, input.importedHead], {\n        timeout: 60_000,\n        maxBuffer: 256 * 1024,\n      });\n    } catch (error) {\n      const reason = error instanceof Error ? error.message : String(error);\n      throw new Error(\n        `Failed to merge concurrent SSH git histories for ${currentHead.slice(0, 12)} and ${input.importedHead.slice(0, 12)}: ${reason}`,\n      );\n    }\n    const mergedTreeId = mergedTree.stdout.trim().split(\"\\n\")[0]?.trim() ?? \"\";\n    if (!mergedTreeId) {\n      throw new Error(\"Failed to compute a merged git tree for SSH workspace restore.\");\n    }\n\n    const mergeCommit = await runLocalGit(\n      input.localDir,\n      [\n        \"commit-tree\",\n        mergedTreeId,\n        \"-p\",\n        currentHead,\n        \"-p\",\n        input.importedHead,\n        \"-m\",\n        `Paperclip SSH sync merge ${input.importedHead.slice(0, 12)}`,\n      ],\n      {\n        timeout: 60_000,\n        maxBuffer: 64 * 1024,\n      },","sourceCodeStart":953,"sourceCodeEnd":989,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/ssh.ts#L953-L989","documentation":"Thrown during SSH workspace restore when `git merge-tree --write-tree` exited successfully but its stdout first line was empty, so no merged tree object id could be extracted. This is an unexpected git output shape: the command did not error but produced no usable tree id, so the subsequent commit-tree step cannot proceed.","triggerScenarios":"mergeConcurrentSshGitHistories runs merge-tree --write-tree successfully (no exception) but mergedTree.stdout.trim().split('\\n')[0] is empty. Can happen with unusual git versions that emit a different first-line format, or when stdout is whitespace-only due to an upstream pipe/buffer issue.","commonSituations":"A git version mismatch on the host producing unexpected merge-tree output; an edge case where merge-tree writes a trailing-newline-only output for already-merged trees; an environment with a git alias or wrapper that mangles stdout.","solutions":["Check the installed git version matches Paperclip expectations (merge-tree --write-tree requires a modern git >= 2.38); upgrade git if old.","Run the same merge-tree command manually in input.localDir and inspect raw stdout to see what the first line actually is.","If currentHead and importedHead produce an empty merge-tree result, confirm both refs are valid non-empty commits.","Report with the git version and raw stdout if the output shape is genuinely malformed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const out = await runLocalGit(localDir, [\"merge-tree\", \"--write-tree\", currentHead, importedHead]);\nconst treeId = out.stdout.trim().split(\"\\n\")[0]?.trim();\nif (!treeId) {\n  throw new Error(\"merge-tree produced no tree id; check git version\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin a modern git (>= 2.38) that supports merge-tree --write-tree with stable output.","Unit-test the restore merge path against the deployed git version in CI.","Surface the installed git version in diagnostics when this fires."],"tags":["git","ssh","workspace-restore","paperclip"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}