mastra-ai/mastra · error · MaterializeError
pull-failed
pull-failed
Error message
Failed to set git remote: ${setUrl.stderr} What it means
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.
Source
Thrown at mastracode/factory/src/integrations/github/sandbox.ts:321
sandbox,
`mkdir -p ${shellQuote(workdir)} && find ${shellQuote(workdir)} -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +`,
);
},
},
);
if (clone.exitCode !== 0) {
// git can fail after creating the checkout ("Clone succeeded, but
// checkout failed") with the tokenized origin persisted — probe the
// disk instead of assuming the failed clone left nothing behind.
tokenInRemote = await hasGitDir(sandbox, workdir);
throw classifyGitFailure(clone, 'clone-failed');
}
tokenInRemote = true;
} else {
// 2b. Re-open: refresh remote to the token URL and fast-forward pull.
const setUrl = await sh(sandbox, `git -C ${shellQuote(workdir)} remote set-url origin ${shellQuote(authUrl)}`);
if (setUrl.exitCode !== 0) {
throw new MaterializeError(`Failed to set git remote: ${setUrl.stderr}`, 'pull-failed');
}
tokenInRemote = true;
const pull = await gitTransfer(sandbox, `git -C ${shellQuote(workdir)} pull --ff-only`, {
phase: 'repository pull',
});
if (pull.exitCode !== 0) {
if (!isBenignNonFastForward(pull)) {
throw classifyGitFailure(pull, 'pull-failed');
}
// The workdir was left on a session's working branch that can't be
// fast-forwarded (diverged from upstream, no upstream, or detached
// HEAD), or its configured upstream ref was deleted after merge.
// That checkout still holds usable work — never rebase or reset it
// here. Leave it as-is and let the session reconcile with the remote
// itself.
}
}
} catch (primary) {View on GitHub (pinned to 75dd419e61)
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.
Defensive patterns
Strategy: retry
Validate before calling
const check = await sh(sandbox, `git -C ${shellQuote(workdir)} rev-parse --git-dir`);
if (check.exitCode !== 0) {
// not a git repo anymore — clear the binding so the flow re-clones instead of pulling
await resetMaterialization(storage, sandboxRow);
} Try / catch
try {
await materializeRepo(options);
} catch (err) {
if (err instanceof MaterializeError && err.code === 'pull-failed' && err.message.startsWith('Failed to set git remote')) {
await resetMaterialization(storage, sandboxRow); // drop row/workdir
return materializeRepo(options); // fresh clone path
}
throw err;
} Prevention
- 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.
When it happens
Trigger: `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.
Common situations: 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.
Related errors
- git-missing
- commit-failed
- Not found at ref ${ref}: ${path}
- Sandbox workspace root resolution returned an empty path
- Path escapes workspace root: ${inputPath}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/361842ddcd90f3de.
Report an issue: GitHub.