Summary
On Android, voice capture in the installed Ta-Da PWA can fail with:
Unexpected token '<', "<!DOCTYPE "... is not valid JSON
The report came from the Moments screen on a stale installed origin:
https://app.tada.living/moments
Current production appears to be https://tada.living, and app.tada.living no longer resolves in DNS from the reporting environment. That suggests an older installed PWA may still be pinned to a dead legacy origin.
Why this matters
Even if the stale origin is the main trigger, the client-side voice fallback is currently brittle: it assumes failed responses from /api/voice/transcribe are JSON, so any HTML/login/error page crashes the recorder path instead of degrading gracefully.
Relevant code
app/composables/useTranscription.ts
Around the cloud-transcription fallback:
fetch("/api/voice/transcribe", ...)
- on failure:
await response.json().catch(() => ({}))
- on success:
await response.json()
In the current file this is around lines 472-488.
Likely failure mode
- User has an installed Android PWA from old origin
app.tada.living
- Relative API call to
/api/voice/transcribe hits a stale/invalid host or session path
- Server/proxy returns HTML (login page, redirect page, error page, or generic app shell)
- Client blindly calls
response.json()
- Recorder path throws
Unexpected token '<'
Expected behaviour
- Voice capture should fail with a readable error, not a JS parse crash
- If the app is running from an obsolete origin, the UI should surface that clearly
- If
app.tada.living is meant to die, legacy installed PWAs may need a redirect or migration path
Suggested directions
- Harden
useTranscription.ts to inspect content type / response text before parsing JSON
- Special-case HTML/login responses from
/api/voice/transcribe
- Decide whether to restore or redirect
app.tada.living, or explicitly force reinstall from tada.living
- Consider whether other voice/LLM endpoints have the same brittle
response.json() assumption
Field evidence
- Error observed on Android stream at
https://app.tada.living/moments
tada.living is the live hostname referenced in repo/docs/config
app.tada.living did not resolve during follow-up checks from Block
Note
No local patch is being proposed here because deploy/build is currently being handled from VS Code by another agent workflow; this issue is to preserve the diagnosis and make the fix/release path explicit.
Summary
On Android, voice capture in the installed Ta-Da PWA can fail with:
Unexpected token '<', "<!DOCTYPE "... is not valid JSONThe report came from the Moments screen on a stale installed origin:
https://app.tada.living/momentsCurrent production appears to be
https://tada.living, andapp.tada.livingno longer resolves in DNS from the reporting environment. That suggests an older installed PWA may still be pinned to a dead legacy origin.Why this matters
Even if the stale origin is the main trigger, the client-side voice fallback is currently brittle: it assumes failed responses from
/api/voice/transcribeare JSON, so any HTML/login/error page crashes the recorder path instead of degrading gracefully.Relevant code
app/composables/useTranscription.tsAround the cloud-transcription fallback:
fetch("/api/voice/transcribe", ...)await response.json().catch(() => ({}))await response.json()In the current file this is around lines 472-488.
Likely failure mode
app.tada.living/api/voice/transcribehits a stale/invalid host or session pathresponse.json()Unexpected token '<'Expected behaviour
app.tada.livingis meant to die, legacy installed PWAs may need a redirect or migration pathSuggested directions
useTranscription.tsto inspect content type / response text before parsing JSON/api/voice/transcribeapp.tada.living, or explicitly force reinstall fromtada.livingresponse.json()assumptionField evidence
https://app.tada.living/momentstada.livingis the live hostname referenced in repo/docs/configapp.tada.livingdid not resolve during follow-up checks from BlockNote
No local patch is being proposed here because deploy/build is currently being handled from VS Code by another agent workflow; this issue is to preserve the diagnosis and make the fix/release path explicit.