{"record":{"id":"361842ddcd90f3de","repo":"mastra-ai/mastra","slug":"pull-failed","errorCode":"pull-failed","errorMessage":"Failed to set git remote: ${setUrl.stderr}","messagePattern":"Failed to set git remote: (.+?)","errorType":"error_code","errorClass":"MaterializeError","httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/integrations/github/sandbox.ts","lineNumber":321,"sourceCode":"              sandbox,\n              `mkdir -p ${shellQuote(workdir)} && find ${shellQuote(workdir)} -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +`,\n            );\n          },\n        },\n      );\n      if (clone.exitCode !== 0) {\n        // git can fail after creating the checkout (\"Clone succeeded, but\n        // checkout failed\") with the tokenized origin persisted — probe the\n        // disk instead of assuming the failed clone left nothing behind.\n        tokenInRemote = await hasGitDir(sandbox, workdir);\n        throw classifyGitFailure(clone, 'clone-failed');\n      }\n      tokenInRemote = true;\n    } else {\n      // 2b. Re-open: refresh remote to the token URL and fast-forward pull.\n      const setUrl = await sh(sandbox, `git -C ${shellQuote(workdir)} remote set-url origin ${shellQuote(authUrl)}`);\n      if (setUrl.exitCode !== 0) {\n        throw new MaterializeError(`Failed to set git remote: ${setUrl.stderr}`, 'pull-failed');\n      }\n      tokenInRemote = true;\n      const pull = await gitTransfer(sandbox, `git -C ${shellQuote(workdir)} pull --ff-only`, {\n        phase: 'repository pull',\n      });\n      if (pull.exitCode !== 0) {\n        if (!isBenignNonFastForward(pull)) {\n          throw classifyGitFailure(pull, 'pull-failed');\n        }\n        // The workdir was left on a session's working branch that can't be\n        // fast-forwarded (diverged from upstream, no upstream, or detached\n        // HEAD), or its configured upstream ref was deleted after merge.\n        // That checkout still holds usable work — never rebase or reset it\n        // here. Leave it as-is and let the session reconcile with the remote\n        // itself.\n      }\n    }\n  } catch (primary) {","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/github/sandbox.ts#L303-L339","documentation":"On re-open of an already-materialized repo, materializeRepo refreshes the origin remote to the authenticated token URL via `git remote set-url origin <authUrl>`; a non-zero exit throws this MaterializeError with code pull-failed, embedding git's stderr. The re-open pull flow can't authenticate without resetting the remote URL, so it aborts.","triggerScenarios":"`git remote set-url` failing inside the sandbox because the workdir is no longer a git repository (wiped/partial .git), the filesystem is read-only or full, origin was deleted, or the sandbox process is denied executing git.","commonSituations":"A sandbox disk restored from a checkpoint where .git was lost while files remained; sandbox volume full; workdir manually modified by a user's session commands.","solutions":["Inspect the embedded stderr in the message for the underlying git cause.","Reset the binding so the workdir is re-cloned (delete the sandbox workdir or the materialization row) and retry.","Free sandbox disk space or fix filesystem permissions if stderr indicates ENOSPC/EACCES.","Re-run materialization with a fresh sandbox instance."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const check = await sh(sandbox, `git -C ${shellQuote(workdir)} rev-parse --git-dir`);\nif (check.exitCode !== 0) {\n  // not a git repo anymore — clear the binding so the flow re-clones instead of pulling\n  await resetMaterialization(storage, sandboxRow);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await materializeRepo(options);\n} catch (err) {\n  if (err instanceof MaterializeError && err.code === 'pull-failed' && err.message.startsWith('Failed to set git remote')) {\n    await resetMaterialization(storage, sandboxRow); // drop row/workdir\n    return materializeRepo(options); // fresh clone path\n  }\n  throw err;\n}","preventionTips":["Don't mutate .git/config from session tooling; keep git metadata intact.","Keep sandbox disk usage below quota so config writes can't fail with ENOSPC.","Reset bindings whose workdir shows a missing .git rather than pulling blindly.","Parse embedded stderr to distinguish transient (disk) from structural (no repo) causes."],"tags":["git","sandbox","pull","filesystem"],"backgroundTag":"git-command-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}