Skip to content

Android PWA can crash on voice capture with Unexpected token '<' when installed from stale app.tada.living origin #13

Description

@InfantLab

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

  1. User has an installed Android PWA from old origin app.tada.living
  2. Relative API call to /api/voice/transcribe hits a stale/invalid host or session path
  3. Server/proxy returns HTML (login page, redirect page, error page, or generic app shell)
  4. Client blindly calls response.json()
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions