Skip to content

fix(speech): filter undefined voices from getVoicesAsync#1239

Open
sentry[bot] wants to merge 1 commit into
developfrom
seer/fix/speech-filter-undefined-voices
Open

fix(speech): filter undefined voices from getVoicesAsync#1239
sentry[bot] wants to merge 1 commit into
developfrom
seer/fix/speech-filter-undefined-voices

Conversation

@sentry

@sentry sentry Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

The TypeError: undefined is not an object (evaluating 'Object.getPrototypeOf(voice)') occurred when iterating over the voices array returned by window.speechSynthesis.getVoices(). This was observed specifically on Brave browser on iOS 18.7, where the browser's implementation of getVoices() could return an array containing undefined elements.

This fix modifies the getVoicesAsync function in apps/web/src/utils/speech.ts to filter out any falsy (including undefined) values from the array returned by window.speechSynthesis.getVoices() before resolving the promise. This ensures that only valid SpeechSynthesisVoice objects are processed, preventing the TypeError.

Fixes ECENCY-NEXT-1GJH

@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes a TypeError crash on Brave browser iOS 18.7 where window.speechSynthesis.getVoices() returns an array that can contain undefined elements, causing a downstream failure in Object.getPrototypeOf(voice).

  • Adds .filter(Boolean) as SpeechSynthesisVoice[] to both code paths in getVoicesAsync — the synchronous return branch and the voiceschanged event handler — ensuring only valid SpeechSynthesisVoice objects are resolved.
  • The fix is minimal, correctly targeted, and applied consistently across both branches of the function.

Confidence Score: 4/5

Safe to merge — the change is a two-line defensive filter applied symmetrically to both code paths with no behavioral change for well-formed browsers.

The fix is correct and minimal. The only gap is the absence of a regression test, which the project's own guidelines call for on bug fixes. Without it, the specific crash condition (undefined elements in getVoices()) has no automated guard against future regression.

Files Needing Attention: apps/web/src/utils/speech.ts — functional fix is fine, but a regression test covering the undefined-element case is missing.

Important Files Changed

Filename Overview
apps/web/src/utils/speech.ts Adds .filter(Boolean) to both getVoices() call sites to strip undefined elements before resolving; fix is correct and symmetric. No regression test included despite project guidelines requiring one for bug fixes.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant getVoicesAsync
    participant speechSynthesis

    Caller->>getVoicesAsync: call()
    getVoicesAsync->>speechSynthesis: getVoices()
    speechSynthesis-->>getVoicesAsync: voices[] (may contain undefined)
    getVoicesAsync->>getVoicesAsync: .filter(Boolean) as SpeechSynthesisVoice[]
    alt "voices.length > 0"
        getVoicesAsync-->>Caller: resolve(filteredVoices)
    else voices empty
        getVoicesAsync->>speechSynthesis: addEventListener("voiceschanged", handler)
        speechSynthesis-->>getVoicesAsync: voiceschanged event fires
        getVoicesAsync->>speechSynthesis: getVoices()
        speechSynthesis-->>getVoicesAsync: voices[] (may contain undefined)
        getVoicesAsync->>getVoicesAsync: .filter(Boolean) as SpeechSynthesisVoice[]
        getVoicesAsync->>speechSynthesis: removeEventListener("voiceschanged", handler)
        getVoicesAsync-->>Caller: resolve(filteredVoices)
    end
Loading

Comments Outside Diff (1)

  1. apps/web/src/utils/speech.ts, line 1-14 (link)

    P2 Missing regression test for the bug fix

    The project's own guidelines (CLAUDE.md) state that bug fixes should include regression tests. getVoicesAsync is a pure utility function that is straightforward to unit-test with Vitest: mock window.speechSynthesis.getVoices to return [undefined, voiceObj] and assert the resolved array contains only the valid voice. Without this, the crash can silently regress if the filter is ever removed or refactored.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

    Fix in Claude Code

Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix(speech): filter undefined voices fro..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants