When the solve command attempted to work on an issue in an empty repository (no commits), it failed silently during branch creation instead of providing actionable guidance or automatically resolving the problem.
- User runs solve command against
https://github.com/DeepYV/Healora/issues/1 - Repository access check passes - User has write access to the private repository
- Clone succeeds - Empty repository is cloned (a valid operation)
- Default branch detection succeeds - Returns
main(from HEAD symbolic ref) - Branch creation fails -
git checkout -b issue-1-xxx origin/mainfails becauseorigin/mainis not a valid commit (no commits exist) - Error message is misleading - Suggests branch name conflicts, uncommitted changes, or git config issues, none of which are the actual problem
The repository DeepYV/Healora was completely empty (no commits, no files). When attempting to create a branch from origin/main, git fails with:
fatal: 'origin/main' is not a commit and a branch 'issue-1-4529e36b433e' cannot be created from it
-
Existing empty repo handling was fork-only: The codebase already had
tryInitializeEmptyRepository()insolve.repository.lib.mjs, but it was only triggered during the fork creation path (HTTP 403 "Empty repositories cannot be forked"). When the user has direct write access, the fork path is skipped entirely. -
No empty repo detection in the direct access path: The
verifyDefaultBranchAndStatus()function checks for empty default branch but doesn't distinguish between "empty repository" and "other git issues." -
Error handler lacks empty repo context:
handleBranchCreationError()suggests generic causes (branch exists, uncommitted changes) without detecting the specific "is not a commit" pattern.
solve.mjs:
├── checkRepositoryWritePermission() → PASS (has write access)
├── setupRepositoryAndClone()
│ ├── setupRepository() → No fork needed (direct access)
│ └── cloneRepository() → SUCCESS (cloning empty repo is valid)
├── verifyDefaultBranchAndStatus()
│ └── git branch --show-current → "" (empty - no commits!)
│ └── THROWS: "Default branch detection failed"
└── createOrCheckoutBranch() → NEVER REACHED
└── git checkout -b ... origin/main → Would fail (no commits)
Added a new CLI option --auto-init-repository that:
- Detects empty repositories via
detectEmptyRepository()- checks for absence of commits and remote branches - Auto-initializes using the existing
tryInitializeEmptyRepository()function (creates README.md via GitHub API) - Re-fetches and continues - After initialization, fetches the new commit, checks out the default branch, and proceeds normally
- When
--auto-init-repositoryis NOT enabled: Clear message suggesting the flag + comment on the issue informing the user - When
--auto-init-repositoryfails: Clear error message + comment on the issue with actionable guidance - When
--auto-init-repositorysucceeds: No issue comment posted (no user action needed) - When branch creation fails due to empty repo: Specific "is not a commit" pattern detection with actionable fix suggestion
- Reuses existing
tryInitializeEmptyRepository()code (DRY principle) - Issue comment behavior mirrors the existing fork-path comment in
solve.repository.lib.mjs
| File | Change |
|---|---|
src/solve.config.lib.mjs |
Added --auto-init-repository option definition |
src/option-suggestions.lib.mjs |
Added to KNOWN_OPTION_NAMES for typo detection |
src/solve.repository.lib.mjs |
Exported tryInitializeEmptyRepository for reuse |
src/solve.repo-setup.lib.mjs |
Added empty repo detection, auto-init, and issue comment in verifyDefaultBranchAndStatus() |
src/solve.mjs |
Pass argv, owner, repo, issueUrl to verifyDefaultBranchAndStatus() |
src/solve.branch-errors.lib.mjs |
Improved error message for empty repo branch creation failures |
- Original solve log - Full log of the failed solve attempt
- GitHub Issue
- Related Issue - The issue that triggered this failure
- PR #361 - Previous fix for empty repo handling (fork path only)
- Edge cases need end-to-end coverage: The empty repo case was handled in the fork path but not the direct access path. Both code paths need the same level of resilience.
- Error messages should diagnose, not just report: The original error message listed generic causes. Pattern-matching on error output (
"is not a commit") enables specific, actionable suggestions. - Reuse existing solutions:
tryInitializeEmptyRepository()already existed and worked correctly - it just needed to be exported and called from the right place.