eyaltoledano/claude-task-master · error
branch already exists: ${branchName}
Error message
branch already exists: ${branchName} What it means
createBranch() checks branchExists(branchName) first and throws when a branch with that exact name already exists locally. The library refuses to silently reuse or overwrite an existing branch. Operations on the new branch never start.
Source
Thrown at packages/tm-core/src/modules/git/adapters/git-adapter.ts:403
*
* @param {string} branchName - Name for the new branch
* @param {Object} options - Branch creation options
* @param {boolean} options.checkout - Whether to checkout after creation
* @returns {Promise<void>}
* @throws {Error} If branch already exists or working tree is dirty (when checkout=true)
*
* @example
* await git.createBranch('feature-branch');
* await git.createBranch('feature-branch', { checkout: true });
*/
async createBranch(
branchName: string,
options: { checkout?: boolean } = {}
): Promise<void> {
// Check if branch already exists
const exists = await this.branchExists(branchName);
if (exists) {
throw new Error(`branch already exists: ${branchName}`);
}
// If checkout is requested, ensure working tree is clean
if (options.checkout) {
await this.ensureCleanWorkingTree();
}
// Create the branch
await this.git.branch([branchName]);
// Checkout if requested
if (options.checkout) {
await this.git.checkout(branchName);
}
}
/**
* Checks out an existing branch.View on GitHub (pinned to c0c98d367c)
Solutions
- Check first with branchExists(name) and reuse or switch to the existing branch.
- Delete the stale branch if unwanted: git branch -D feature/x (or adapter deleteBranch with force).
- Use a unique branch name (append timestamp/task-id) to avoid collisions.
- Make your automation idempotent: catch this error and treat 'already exists' as success.
Example fix
// before
await git.createBranch('feature/x'); // throws if exists
// after
if (!(await git.branchExists('feature/x'))) {
await git.createBranch('feature/x', { checkout: true });
} else {
await git.checkoutBranch('feature/x');
} Defensive patterns
Strategy: validation
Validate before calling
if (await git.branchExists('feature/x')) {
// reuse, switch, or pick a new name before creating
} Try / catch
try {
await git.createBranch('feature/x');
} catch (e) {
if (e instanceof Error && e.message.startsWith('branch already exists')) {
await git.checkoutBranch('feature/x'); // idempotent fallback
return;
}
throw e;
} Prevention
- Always branchExists() before createBranch() in automation.
- Include a unique identifier (task ID, timestamp) in generated branch names.
- Clean up merged branches regularly so names don't collide.
- Make re-runs idempotent by treating 'already exists' as success.
When it happens
Trigger: Calling gitAdapter.createBranch('feature/x') when 'feature/x' already exists (previously created by this workflow, a teammate, or a retried run), regardless of the checkout option.
Common situations: Re-running an idempotency-unaware workflow after a partial failure; branch naming derived from a date/task that repeats; attempting to recreate a branch that was merged but not deleted.
Related errors
- branch does not exist: ${branchName}
- cannot delete current branch: ${branchName}
- NO_CURRENT_BRANCH
- NO_CURRENT_BRANCH
- Failed to fetch tasks from any tag. First error: ${failedTag
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/cf44a572c5a124d0.
Report an issue: GitHub.