Diagnosed on the running “Obeya (checkout)” app today, reproduced with a small test app, fixed in the install step.
app/ lands. The app rebuilds itself in the background and installs the new build: its old bundle is renamed to ….app.old and deleted, while the old app keeps running from it.tccd proc_pidpath_audittoken() failed from PID[80167]: (#2) No such file or directory tccd ERROR: failed to construct a process for the responsible audit token for PID[80169].
PID 80167 is the running app; 80169 is its webview's audio process. macOS identifies the app by the file it was started from, and that file is gone, so the microphone is denied. lsof shows the app still running from Obeya (checkout).app.old/Contents/MacOS/obeya, which no longer exists.
It stays that way until the app starts again. Normally the app restarts itself for the new build once workers pause, but only when it started Obeya itself. Here Obeya runs from bun start in a terminal, so the app never restarted: the microphone stayed dead. That's the “sometimes”: only between an automatic rebuild of the app and its next start.
A minimal ad-hoc-signed app (own bundle ID) asked macOS every 3 s whether it may use the microphone, while its bundle was changed under it:
| Bundle of the running app | macOS's answer |
|---|---|
| in place | 0 = not decided yet (would ask) |
renamed to T.app.old-1 | 0, identity found at the new path |
| deleted | 2 = denied, with the same proc_pidpath… No such file error |
When the checkout app installs a new build of itself on a Mac, the running app's bundle is now moved aside (Obeya (checkout).app.old-… next to it) instead of deleted. A later install removes asides that no process has open any more. The running app keeps its microphone until it restarts into the new build.
Windows and Linux are not affected (no such check there) and behave as before.
The app running right now has already lost its bundle; the fix can't bring that back. Quit the app and open it again, and the microphone works (macOS may ask once to allow it for the new build). From the next rebuild on, the fix prevents it.