#6965 The wrangler setup does not proceed to the next step
Bug confirmed: gitCommit() in C3 lacks try-catch around git commit. When GPG signing fails/cancelled, setup crashes instead of continuing gracefully.
Add try-catch error handling in git.ts gitCommit function to continue on commit failure
Analysis Report
Issue Review: cloudflare/workers-sdk#6965
Summary
wrangler init (now delegated to C3) fails and does not proceed when git commit fails due to GPG signing being cancelled.
Findings
- Created: 2024-10-14
- Updated: 2025-10-30
- Version: 3.80.4 (wrangler) -> 4.60.0 (current wrangler), create-cloudflare@2.62.3 (current)
- Component: create-cloudflare (C3) - git.ts
- Labels: bug
- Comments: 0
Key Evidence
Issue is still reproducible in current code - The
gitCommitfunction inpackages/create-cloudflare/src/git.ts:65-97does NOT have try-catch error handling around the git commit operation:await runCommand(["git", "add", "."], { silent: true, cwd: ctx.project.path, }); await runCommand(["git", "commit", "-m", ctx.commitMessage, "--no-verify"], { silent: true, cwd: ctx.project.path, });Other git operations are properly wrapped - Functions like
initializeGit,isGitConfigured,isInsideGitRepo, andgetProductionBranchall have try-catch blocks to gracefully handle failures.No related PR fixes found - Searched for PRs mentioning:
- Issue #6965 directly - no matches
- "git commit error" - no relevant matches
- "gpg" - no matches
- Changelog mentions of fixing git commit failures - none found
CLI error handling - The main CLI (
cli.ts:221) catches errors at the top level with.catch((e) => {...}), but this causes the entire process to abort rather than gracefully continuing without the commit.Note: While
wrangler initoriginally had this issue, it now delegates tocreate-cloudflare(C3) by default. The bug persists because the underlying git commit code in C3 lacks error handling.
Recommendation
Status: KEEP OPEN
Reasoning: The bug is still present in the current codebase. When a user has GPG signing enabled and cancels the signing prompt (or if signing fails for any reason), the git commit command fails and throws an unhandled error. This causes the entire wrangler init / npm create cloudflare process to abort instead of gracefully continuing with the setup completed but uncommitted.
Action: Add try-catch error handling around the git commit operation in packages/create-cloudflare/src/git.ts to gracefully handle commit failures and allow the setup to complete.
Root Cause Analysis
Problem Location
packages/create-cloudflare/src/git.ts:65-97 - The gitCommit function
Code Reference
export const gitCommit = async (ctx: C3Context) => {
// ... early returns for !ctx.args.git and ctx.gitRepoAlreadyExisted ...
const s = spinner();
s.start("Committing new files");
await runCommand(["git", "add", "."], { // Line 84
silent: true,
cwd: ctx.project.path,
});
await runCommand(["git", "commit", "-m", ctx.commitMessage, "--no-verify"], { // Line 89
silent: true,
cwd: ctx.project.path,
});
s.stop(`${brandColor("git")} ${dim(`commit`)}`);
};
Why This Causes the Bug
- User runs
npx wrangler initornpm create cloudflare - User opts for git version control
- C3 initializes a git repo and adds files
- When attempting to commit,
git commitinvokes GPG for signing (ifcommit.gpgsign=true) - User cancels the GPG prompt or signing fails
git commitreturns non-zero exit coderunCommandthrows an error (seepackages/create-cloudflare/src/helpers/command.ts:93-95)- The error bubbles up and crashes the entire setup process
Comparison with Other Git Functions
Other git-related functions in the same file properly handle errors:
initializeGit(line 215-231): Has try-catch, falls back togit initwithout--initial-branchisGitConfigured(line 163-182): Has try-catch, returnsfalseon errorisInsideGitRepo(line 191-201): Has try-catch, returnsfalseon errorgetProductionBranch(line 236-248): Has try-catch, returns"main"on error
Proposed Solution
Option 1: Graceful Degradation (Recommended)
Wrap the commit operation in try-catch and continue if it fails, notifying the user.
export const gitCommit = async (ctx: C3Context) => {
assert.notStrictEqual(
ctx.args.git,
undefined,
"Expected git context to be defined by now",
);
ctx.commitMessage = await createCommitMessage(ctx);
if (!ctx.args.git) {
return;
}
if (ctx.gitRepoAlreadyExisted) {
return;
}
const s = spinner();
s.start("Committing new files");
try {
await runCommand(["git", "add", "."], {
silent: true,
cwd: ctx.project.path,
});
await runCommand(["git", "commit", "-m", ctx.commitMessage, "--no-verify"], {
silent: true,
cwd: ctx.project.path,
});
s.stop(`${brandColor("git")} ${dim(`commit`)}`);
} catch (error) {
s.stop(`${brandColor("git")} ${dim(`commit skipped`)}`);
updateStatus(
"Failed to create initial commit. You can commit manually later.",
);
}
};
Option 2: Warn and Continue with Details
Provide more context about why the commit failed:
} catch (error) {
s.stop(`${brandColor("git")} ${dim(`commit failed`)}`);
const errorMessage = error instanceof Error ? error.message : String(error);
// Check for common GPG errors
if (errorMessage.includes("gpg") || errorMessage.includes("signing")) {
updateStatus(
"Git commit failed due to GPG signing. Your changes have been staged but not committed.\n" +
"You can commit manually with: git commit -m 'Initial commit' --no-gpg-sign",
);
} else {
updateStatus(
`Git commit failed: ${errorMessage}\nYour changes have been staged but not committed.`,
);
}
}
Implementation Difficulty
Difficulty: Easy
Justification
- Single file change - Only
packages/create-cloudflare/src/git.tsneeds modification - Clear pattern to follow - Other functions in the same file already demonstrate the try-catch pattern
- No architectural changes - Just adding error handling around existing code
- Existing test infrastructure - Tests exist for
gitCommitinpackages/create-cloudflare/src/__tests__/git.test.ts - Low risk - Graceful degradation only improves the user experience; worst case is the current behavior
Files to Modify
| File | Change |
|---|---|
packages/create-cloudflare/src/git.ts |
Add try-catch around git commit operations in gitCommit function |
packages/create-cloudflare/src/__tests__/git.test.ts |
Add test case for commit failure scenario |
Testing Recommendations
Unit Tests
Add test in packages/create-cloudflare/src/__tests__/git.test.ts:
test("commit failure is handled gracefully", async () => {
const ctx = createTestContext("test", { projectName: "test" });
ctx.args.git = true;
// Mock git add to succeed
vi.mocked(runCommand)
.mockResolvedValueOnce("git version 2.20.2") // for createCommitMessage
.mockResolvedValueOnce("") // git add
.mockRejectedValueOnce(new Error("gpg: signing failed: Operation cancelled"));
// Should not throw
await expect(gitCommit(ctx)).resolves.not.toThrow();
// Should have called updateStatus with failure message
expect(updateStatus).toHaveBeenCalledWith(
expect.stringContaining("commit"),
);
});
Manual Testing
- Enable GPG signing:
git config --global commit.gpgsign true - Set up GPG to require password confirmation for each signing
- Run
npm create cloudflare@latest test-project - Select "Yes" for git version control
- When GPG prompt appears, cancel it
- Expected: Setup should complete with a message about skipped commit
- Verify: The project directory should exist with all files, just uncommitted
E2E Testing
Consider adding to packages/create-cloudflare/e2e tests if there's infrastructure to mock git failures.
Suggested Comment
Thank you for reporting this issue! After investigation, this bug is confirmed to still be present in the current codebase.
Root Cause: The
gitCommitfunction inpackages/create-cloudflare/src/git.tsdoesn't have error handling around the git commit operation. When GPG signing is enabled and cancelled (or fails for any reason), the entire setup process crashes instead of gracefully continuing.Fix: Add try-catch error handling to allow the setup to complete even if the commit fails, with a message informing the user they can commit manually.
Note: While this was originally reported for
wrangler init, that command now delegates tocreate-cloudflare(C3), so the fix needs to be applied in the C3 package.This should be a straightforward fix - the same try-catch pattern is already used in other git functions in the same file.
Notes & Feedback (0)
No notes yet.