The installer for this tool needed to know one thing about the user's Claude Code installation: are they logged in?

The check was a directory existence test:

if [ -d "$HOME/.claude" ]; then
    echo "  [OK] Claude login found"
else
    echo "  You need to log in to Claude."
    claude auth login
fi

The intent is clear. The implementation is wrong in a specific way that matters more than it sounds.

~/.claude exists for any prior use of Claude Code on this machine. Run claude once in your life — to look at the help, to start a session and immediately quit, to experiment with a feature — and the directory is there. It contains settings, caches, history files. It is not a credential file. It is just the place the tool puts its stuff.

The directory is created on first invocation, before any login prompt. So a user who has touched Claude Code but never completed login has the directory. The installer sees it, says "login found," skips the auth step. The user proceeds. The user then runs the aaicase tool, which tries to spawn a Claude query, which throws an auth error.

From the user's perspective the install went fine. The OK lines all printed in green. They run the tool. The tool fails. They have no idea why. They re-read the install instructions, see nothing about logging in (because the installer told them they already were), and start filing support requests.

What the installer actually wanted to know

The right question isn't "does the config directory exist?" — it's "is the user authenticated right now?" Claude Code has a subcommand for exactly that:

$ claude auth status
{
  "loggedIn": true,
  "authMethod": "claude.ai",
  "apiProvider": "firstParty",
  "email": "user@example.com",
  ...
}
$ echo $?
0

Exit 0 when logged in, non-zero when not. The fix is one line:

if claude auth status &> /dev/null; then
    echo "  [OK] Claude login confirmed"
else
    echo "  You need to log in to Claude. A browser will open."
    claude auth login
fi

This is the functional check the directory existence was approximating. The directory existed as a coincidental side effect of any Claude use; the exit code of auth status is the actual signal.

Why directory-existence checks for state are tempting and wrong

This is a specific instance of a broader anti-pattern: using a filesystem artifact as a proxy for runtime state. The artifact is easy to check (one stat call), free to test, and looks reasonable on inspection. The problem is that the artifact's lifecycle and the state's lifecycle aren't aligned.

The config directory's lifecycle: created on first tool invocation, deleted only if the user manually removes it, persists across uninstalls.

The login state's lifecycle: created when the user authenticates, invalidated when the user logs out OR when credentials expire OR when the auth scheme changes OR when the user manually clears credentials.

The two lifecycles overlap most of the time but not always. The cases where they diverge are exactly the cases that produce bugs:

The right primitive is a function that returns the current state. If the underlying tool exposes one (auth status, --version, a health-check endpoint, a lock file), use it. The filesystem artifact is a proxy for the state only by accident.

Two smaller fixes in the same release

The probe round also found two other installer bugs:

Missing error check on npm install -g @anthropic-ai/claude-code. Both Mac and Windows installers ran the install without checking the exit code. If npm failed (no network, registry unreachable, permission denied), the script proceeded to the next step with claude missing. The user then saw a chain of "claude not found" errors from the aaicase install instead of the actual cause. Added explicit exit-code check with a typed error and suggested remediation (sudo on POSIX, network/permissions diagnosis everywhere).

Stale entry in the worker's installer allowlist. The Cloudflare Worker that serves the install URL had install.sh in its valid-installers array, but the file was never uploaded to R2 (the actual installer is install-mac.sh). Anyone who tried to fetch /install.sh got a 404. Harmless but dead code; removed.

What was different about probing installers

Most probe rounds this month have targeted runtime code — the CLI commands, the library functions, the agent loop. Install scripts run once per machine and never again. They don't have stress tests. They don't fire in CI. The way to probe them is to read them, walk through the failure paths manually, and ask "what does this assume about the system state?"

Two of the three bugs in this release were the kind that only show up the very first time a new user installs. After that, the user's environment is whatever it is, and the installer's edge cases don't fire again for them. So the bugs persist invisibly — every new user trips on the same false-positive, gets the same confused install, files the same support request, and the next user has the same experience.

The lesson: surfaces that run rarely have higher bug density per line than surfaces that run continuously, because nobody notices. Install scripts, configuration migration scripts, one-time setup wizards — all of them benefit from a code-read pass with the question "what happens when this assumption is wrong?"

The version on the install URL is 4.5.112.