On every startup, the cleanup service throws repeated env_cleanup_error log entries for any repository where the default branch is not main and origin/HEAD is not set (e.g. repos using master). The error message itself tells users to set worktree.baseBranch in .archon/config.yaml — but this config value is silently ignored, making the suggestion ineffective.
Log output:
{"level":40,"module":"git","repoPath":"/home/user/myrepo","msg":"default_branch_detection_failed"}
{"level":50,"module":"cleanup","err":{"message":"Cannot detect default branch for /home/user/myrepo:
neither origin/HEAD nor origin/main exist. Set worktree.baseBranch in .archon/config.yaml to specify
the branch explicitly."},"msg":"env_cleanup_error"}
This repeats three times per startup (once per tracked environment) and never resolves regardless of what is written in .archon/config.yaml.
To reproduce
Have a git repository with master as the default branch and no origin/HEAD set
Create .archon/config.yaml in the repo root with:
yaml
worktree:
baseBranch: master
Start Archon (bun run dev)
Observe repeated env_cleanup_error entries in the logs — the config has no effect
You can verify origin/HEAD is not set with:
bash
git symbolic-ref refs/remotes/origin/HEAD
# fatal: ref refs/remotes/origin/HEAD is not a symbolic ref
Expected behaviour
When worktree.baseBranch is set in .archon/config.yaml, Archon should use that value as the base branch and skip the git auto-detection entirely. No errors should appear on startup.
Root cause
loadRepoConfig in packages/core/src/config/config-loader.ts already correctly reads and merges worktree.baseBranch from .archon/config.yaml (lines 454–455). The type is defined, the parsing works, the merge works.
The problem is in packages/core/src/services/cleanup-service.ts around line 310, where getDefaultBranch(mainRepoPath) is called directly without first consulting the repo config:
typescript// Current (broken):
const mainRepoPath = toRepoPath(env.codebase_default_cwd);
const mainBranch = await getDefaultBranch(mainRepoPath);
loadRepoConfig is not imported in cleanup-service.ts at all. The pattern for doing this correctly already exists in packages/git/src/repo.ts line 100:
typescript
const branchToSync = baseBranch ?? (await getDefaultBranch(workspacePath));
Suggested fix
Two small changes to packages/core/src/services/cleanup-service.ts:
- Add imports alongside the existing imports at the top of the file:
typescriptimport { loadRepoConfig } from '../config/config-loader';
import { toBranchName } from '@archon/git';
- Replace the getDefaultBranch call (~line 309):
typescript// After (fixed):
const mainRepoPath = toRepoPath(env.codebase_default_cwd);
const repoConfig = await loadRepoConfig(env.codebase_default_cwd);
const mainBranch = repoConfig?.worktree?.baseBranch
? toBranchName(repoConfig.worktree.baseBranch.trim())
: await getDefaultBranch(mainRepoPath);
No other files need to change.
How to test
Before the fix — confirm the bug:
Set up a repo with master as default branch, no origin/HEAD
Add .archon/config.yaml with worktree.baseBranch: master
Start Archon and observe env_cleanup_error still appears
After the fix — confirm it works:
Same setup as above
Start Archon — logs should show server_ready and cleanup_completed with errors: 0, no env_cleanup_error
A unit test should be added to the cleanup service test suite verifying that when loadRepoConfig returns a config with worktree.baseBranch set, getDefaultBranch is never called and no error is thrown.
## Impact
- Affected workflows/commands:
- Reproduction rate: Always / Intermittent / Once
- Workaround available? If so, describe:
- Data loss risk? (`Yes/No`)
## Scope
- Package(s) likely involved: `core|workflows|isolation|git|adapters|server|web|cli|paths`
- Module (if known): e.g. `workflows:executor`, `adapters:slack`
On every startup, the cleanup service throws repeated env_cleanup_error log entries for any repository where the default branch is not main and origin/HEAD is not set (e.g. repos using master). The error message itself tells users to set worktree.baseBranch in .archon/config.yaml — but this config value is silently ignored, making the suggestion ineffective.
This repeats three times per startup (once per tracked environment) and never resolves regardless of what is written in .archon/config.yaml.
To reproduce
Have a git repository with master as the default branch and no origin/HEAD set
Create .archon/config.yaml in the repo root with:
Start Archon (bun run dev)
Observe repeated env_cleanup_error entries in the logs — the config has no effect
You can verify origin/HEAD is not set with:
Expected behaviour
When worktree.baseBranch is set in .archon/config.yaml, Archon should use that value as the base branch and skip the git auto-detection entirely. No errors should appear on startup.
Root cause
loadRepoConfig in packages/core/src/config/config-loader.ts already correctly reads and merges worktree.baseBranch from .archon/config.yaml (lines 454–455). The type is defined, the parsing works, the merge works.
The problem is in packages/core/src/services/cleanup-service.ts around line 310, where getDefaultBranch(mainRepoPath) is called directly without first consulting the repo config:
typescript// Current (broken):
loadRepoConfig is not imported in cleanup-service.ts at all. The pattern for doing this correctly already exists in packages/git/src/repo.ts line 100:
typescript
const branchToSync = baseBranch ?? (await getDefaultBranch(workspacePath));Suggested fix
Two small changes to packages/core/src/services/cleanup-service.ts:
typescript// After (fixed):
No other files need to change.
How to test
Before the fix — confirm the bug:
Set up a repo with master as default branch, no origin/HEAD
Add .archon/config.yaml with worktree.baseBranch: master
Start Archon and observe env_cleanup_error still appears
After the fix — confirm it works:
Same setup as above
Start Archon — logs should show server_ready and cleanup_completed with errors: 0, no env_cleanup_error
A unit test should be added to the cleanup service test suite verifying that when loadRepoConfig returns a config with worktree.baseBranch set, getDefaultBranch is never called and no error is thrown.