← Back to PRs

#3561: fix: fail fast when both state dirs exist

by adityarao3 open 2026-01-28 20:41 View on GitHub →
cli commands
Fixes #3533 ## Problem When both `~/.clawdbot` (legacy) and `~/.moltbot` (new) state directories exist, Moltbot enters a split-brain state: - Pairing appears to succeed (`paired.json` contains the device) - But the gateway returns: `disconnected (1008): pairing required` or `unauthorized` - The warning "State dir migration skipped: target already exists" was printed, but Moltbot continued running This happens because different parts of the system read/write different directories, causing credentials and pairing data to be stored in one location but read from another. ## Solution Moltbot now refuses to start if both directories exist, displaying a clear error message with resolution options: State directory conflict: both legacy and new directories exist. Legacy: ~/.clawdbot New: ~/.moltbot To fix, choose ONE of these options: Keep the legacy directory (recommended if you have existing data): Remove or rename ~/.moltbot Use the new directory: Remove or rename ~/.clawdbot Merge manually, then remove the legacy directory Set an explicit state directory: export MOLTBOT_STATE_DIR="~/.moltbot" ## Changes - Add `StateDirConflictError` class for explicit error handling - Add `detectStateDirConflict()` for early detection at CLI startup - Throw error instead of warning in `autoMigrateLegacyStateDir()` - Add comprehensive tests for conflict detection ## Testing - Added 6 new tests for `detectStateDirConflict()` - Updated existing test to expect `StateDirConflictError` instead of warning - All unit tests pass <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR aims to prevent a split-brain state when both legacy and newer state directories exist by introducing a dedicated `StateDirConflictError`, improving the user-facing remediation message, and updating state-dir migration behavior to throw instead of only warning. It also adds unit tests around conflict detection. Main integration points are the state migration layer (`src/infra/state-migrations.ts`) and path resolution utilities (`src/config/paths.ts`). The intended UX is to fail fast at CLI startup when both dirs exist, rather than continuing with inconsistent reads/writes. <h3>Confidence Score: 3/5</h3> - Moderately safe to merge, but key wiring issues may prevent the intended fail-fast behavior. - The core idea (throwing on conflict) is sound and tests were added, but the CLI entrypoint currently only imports the new functions without invoking them, and the conflict detector/message use different env var names than the rest of the codebase. Those issues could lead to either no fail-fast at all or confusing remediation instructions. - src/cli/run-main.ts, src/config/paths.ts, src/infra/state-migrations.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs