Bug
The Electron app can render an empty board even when the daemon has projects and
sessions, if the daemon reports the same checkout path with different casing.
Observed locally on macOS:
daemon workingDirectory: /Users/anirudhsharma/documents/projects/reverbcode/backend
Electron expected cwd: /Users/anirudhsharma/Documents/projects/ReverbCode/backend
Those paths resolve to the same directory on the local filesystem, but the app
treated them as different checkouts.
Analyzed against: a4e0458 | Confidence: High
Reproduction
On a macOS checkout where the daemon was started from a differently cased path:
cd frontend
nvm use 20
npm run dev
The daemon API still has data:
/tmp/ao project ls --json
/tmp/ao session ls --json
But the Electron renderer shows:
No projects yet.
Click + above to register a git repo.
Inspecting the live Electron renderer showed:
{
"state": "error",
"message": "Another AO daemon is already running from /Users/.../documents/projects/reverbcode/backend; expected this checkout at /Users/.../Documents/projects/ReverbCode/backend."
}
At the same time, direct renderer fetches to /api/v1/projects and
/api/v1/sessions returned the expected project and sessions.
Root Cause
frontend/src/main.ts compared daemon identity paths with string-normalized
path.resolve() values. That only lowercased paths on Windows.
macOS filesystems are often case-insensitive but case-preserving, so the same
directory can be observed as both documents/projects/reverbcode and
Documents/projects/ReverbCode. The daemon identity check then returned an
error status, and the renderer refused to trust the daemon API base URL.
Fix
Canonicalize path identity through realpathSync.native() before comparing
daemon checkout paths. Preserve the existing behavior of rejecting genuinely
different checkouts, and keep Windows comparisons case-insensitive.
The fix also handles non-existent child paths by canonicalizing the nearest
existing ancestor before applying the remaining path segments.
Impact
This can make the Electron app look empty or unable to use existing daemon data
even though the daemon is healthy and API calls return projects/sessions. It is
especially likely on macOS when a checkout or daemon was launched through paths
with different casing.
Bug
The Electron app can render an empty board even when the daemon has projects and
sessions, if the daemon reports the same checkout path with different casing.
Observed locally on macOS:
Those paths resolve to the same directory on the local filesystem, but the app
treated them as different checkouts.
Analyzed against:
a4e0458| Confidence: HighReproduction
On a macOS checkout where the daemon was started from a differently cased path:
cd frontend nvm use 20 npm run devThe daemon API still has data:
But the Electron renderer shows:
Inspecting the live Electron renderer showed:
{ "state": "error", "message": "Another AO daemon is already running from /Users/.../documents/projects/reverbcode/backend; expected this checkout at /Users/.../Documents/projects/ReverbCode/backend." }At the same time, direct renderer fetches to
/api/v1/projectsand/api/v1/sessionsreturned the expected project and sessions.Root Cause
frontend/src/main.tscompared daemon identity paths with string-normalizedpath.resolve()values. That only lowercased paths on Windows.macOS filesystems are often case-insensitive but case-preserving, so the same
directory can be observed as both
documents/projects/reverbcodeandDocuments/projects/ReverbCode. The daemon identity check then returned anerror status, and the renderer refused to trust the daemon API base URL.
Fix
Canonicalize path identity through
realpathSync.native()before comparingdaemon checkout paths. Preserve the existing behavior of rejecting genuinely
different checkouts, and keep Windows comparisons case-insensitive.
The fix also handles non-existent child paths by canonicalizing the nearest
existing ancestor before applying the remaining path segments.
Impact
This can make the Electron app look empty or unable to use existing daemon data
even though the daemon is healthy and API calls return projects/sessions. It is
especially likely on macOS when a checkout or daemon was launched through paths
with different casing.