Skip to content

fix(cli): create the Maple home before first-run startup touches its siblings - #446

Open
JeremyFunk wants to merge 1 commit into
mainfrom
worktree-cli-first-run-datadir
Open

fix(cli): create the Maple home before first-run startup touches its siblings#446
JeremyFunk wants to merge 1 commit into
mainfrom
worktree-cli-first-run-datadir

Conversation

@JeremyFunk

@JeremyFunk JeremyFunk commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Reported from a fresh install: the first maple start on a machine with no ~/.maple dies with a bare filesystem error.

ERROR (#3): @maple/cli/ServerError: ENOENT: no such file or directory,
mkdir '/Users/…/.maple/data.maple-maintenance-lock'

Why it happens

start reconciles checkpoint recovery before it creates any directory — deliberately, so a restore or reset transaction is settled before reset/compatibility/dirty-store logic runs. That reconciliation takes the maintenance lock, and the lock — like the PID file, the --background log, the restore/reset transactions and the migration journal — is a sibling of the data dir. On first run its parent (~/.maple) does not exist, so the mkdir fails.

acquireMaintenance has created that parent since v0.0.15 (9b5ea73), so the crash only reproduces on older builds — the report is from a Homebrew install still on 0.0.13. There was no test holding the invariant, and it was an emergent property of one helper rather than a stated precondition of startup.

Change

  • start creates the data dir's parent as its first filesystem step. The data dir itself is still created where it was, after recovery reconciliation, so restore/reset reconciliation keeps seeing the tree exactly as it left it.
  • Two regression tests, both against a data dir whose parent is absent: maintenance-lock acquisition, and recovery reconciliation. Removing the parent creation from acquireMaintenance makes both fail with the reported ENOENT.

Verification

  • bun run test in apps/cli — 434 pass, 0 fail.
  • bun typecheck in apps/cli — clean.
  • HOME=<empty dir> maple start from source: creates ~/.maple/data and reaches chDB open (which then stops on libchdb not found, expected in a source checkout — release bundles ship it). Before the fix the same run on 0.0.13's code path stops at the lock mkdir.

Note for the reporter: the Homebrew tap is still serving 0.0.13, several tags behind. brew upgrade will only pick this up once the tap formula is bumped.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…siblings

On a machine with no `~/.maple`, `maple start` fails with a bare
`ENOENT … mkdir '~/.maple/data.maple-maintenance-lock'`: startup reconciles
checkpoint recovery under the maintenance lock before it creates any
directory, and the lock — like the PID file, the `--background` log, the
restore/reset transactions and the migration journal — is a *sibling* of the
data dir, so it lands in a parent that does not exist yet.

`acquireMaintenance` has created that parent since v0.0.15, which is why the
crash only reproduces on older builds. Make the precondition explicit instead
of leaving it to whichever helper happens to run first: create the data dir's
parent as `start`'s first filesystem step, and lock the invariant with two
regression tests (lock acquisition and recovery reconciliation, both against a
data dir whose parent is absent). Both fail with the reported ENOENT when the
parent creation is removed.

The data dir itself is still created where it was, after recovery
reconciliation, so restore/reset reconciliation keeps seeing the tree exactly
as it left it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant