Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

TranscriptBlock: TypeError in updateLines/getLineBoundaries when a chunk has no layout boxes (empty getClientRects)

Open Beginner friendly
#19,733 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@Antreesy is already working on this.

Since Oct 16, 2026.

  • #19868 by @Antreesy — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
javascript
Domain
frontend

Research direction

Start in src/components/CallView/shared/TranscriptBlock.vue at updateLines() and getLineBoundaries(), especially the accesses around lines 292 and 304. Check how the component handles empty getClientRects() results, then exercise transcript updates with an empty or unlaid-out chunk. Done when those cases no longer throw and normal transcript line-boundary behavior remains intact.

Written by the indexing model from the issue text.

Description

bug feature: call 📹 feature: frontend 🖌️
Steps to reproduce
  1. Join a call in a conversation where live transcription is active, so the live transcript panel is rendered and transcript events keep arriving.
  2. Have a transcript chunk whose <span> has no client rectangles — e.g. an empty / whitespace-only message, or the component not being laid out when a transcript arrives.
  3. Keep speaking so handleTranscript fires (partial/final updates).
Actual

Uncaught (in promise) TypeError in the browser console:

TranscriptBlock.vue:292  const lastKnownChunkIndex = this.lines.at(-1)!.lastChunkIndex
  → can't access property "lastChunkIndex", this.lines.at(...) is undefined

Stack:

TranscriptBlock.vue:292 (updateLines → getLineBoundaries)
LiveTranscriptionRenderer.vue:302 (scrollToNextLine)
LiveTranscriptionRenderer.vue:276 (scrollToBottomLineByLine)
LiveTranscriptionRenderer.vue:261 (handleTranscript)
CallParticipantModel.js:438 (_handleTranscript) ← signaling
Cause

TranscriptBlock.updateLines() builds this.lines from this.$refs.chunks[0].getClientRects().length:

this.removeLastChunkFromLines()               // may empty this.lines
if (!this.lines.length) {
  const firstChunkClientRectsLength = this.$refs.chunks[0].getClientRects().length
  for (let i = 0; i < firstChunkClientRectsLength; i++) {
    this.lines.push({ firstChunkIndex: 0, lastChunkIndex: 0 })
  }
}
const lastKnownChunkIndex = this.lines.at(-1)!.lastChunkIndex   // :292

When the chunk has no client rectangles, firstChunkClientRectsLength === 0, nothing is pushed, and this.lines stays empty — then :292 dereferences this.lines.at(-1)!. There is no guard for an empty this.lines. A chunk with zero rects later in the list hits a similar unguarded nextChunkElementClientRects[0].top at :304.

Expected

updateLines() / getLineBoundaries() should not throw when this.lines is empty or a chunk has no client rects — it should just skip.

Suggested fix
const lastLine = this.lines.at(-1)
if (!lastLine) {
  return
}
const lastKnownChunkIndex = lastLine.lastChunkIndex

and a length guard before nextChunkElementClientRects[0].top (~line 304).

Environment

Nextcloud 34.0.4, Talk (spreed) 24.0.5. The same code is present on master (src/components/CallView/shared/TranscriptBlock.vue:280/292).

Dominant language
JavaScript
Stars
2.2k
Forks
598
Avg merge
21h 19m
Merged PRs (30d)
370

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nextcloud/spreed

All issues in nextcloud/spreed

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.