DrKLO/Telegram · error · IOException

Cannot read frame at position {lastDecodePosition}

Error message

Cannot read frame at position {lastDecodePosition}

What it means

FlacExtractor wraps a FlacFrameDecodeException from decoderJni.decodeSampleWithBacktrackPosition(...) as IOException('Cannot read frame at position <lastDecodePosition>'). It records the decoder's last decode position to aid debugging when a frame cannot be read during extraction.

Source

Thrown at TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/flac/FlacExtractor.java:146

  public int read(final ExtractorInput input, PositionHolder seekPosition) throws IOException {
    if (input.getPosition() == 0 && !id3MetadataDisabled && id3Metadata == null) {
      id3Metadata = FlacMetadataReader.peekId3Metadata(input, /* parseData= */ true);
    }

    FlacDecoderJni decoderJni = initDecoderJni(input);
    try {
      decodeStreamMetadata(input);

      if (binarySearchSeeker != null && binarySearchSeeker.isSeeking()) {
        return handlePendingSeek(input, seekPosition, outputBuffer, outputFrameHolder, trackOutput);
      }

      ByteBuffer outputByteBuffer = outputFrameHolder.byteBuffer;
      long lastDecodePosition = decoderJni.getDecodePosition();
      try {
        decoderJni.decodeSampleWithBacktrackPosition(outputByteBuffer, lastDecodePosition);
      } catch (FlacDecoderJni.FlacFrameDecodeException e) {
        throw new IOException("Cannot read frame at position " + lastDecodePosition, e);
      }
      int outputSize = outputByteBuffer.limit();
      if (outputSize == 0) {
        return RESULT_END_OF_INPUT;
      }

      outputSample(outputBuffer, outputSize, decoderJni.getLastFrameTimestamp(), trackOutput);
      return decoderJni.isEndOfData() ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
    } finally {
      decoderJni.clearData();
    }
  }

  @Override
  public void seek(long position, long timeUs) {
    if (position == 0) {
      streamMetadataDecoded = false;
    }

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Handle IOException at the extractor/player level with a resync or skip-to-next-sample strategy.
  2. Ensure the source provides complete, uncorrupted FLAC bytes (check network/CDN integrity).
  3. Use extractor-based seeking so positions are always frame-aligned.

Example fix

// before
// extractor.read() propagates IOException up to player -> playback aborts

// after
try { extractor.read(...); }
catch (IOException e) { /* log position, advance input, continue extraction */ }
Defensive patterns

Strategy: try-catch

Validate before calling

// n/a: extraction-time I/O error caused by corrupt frames; mitigate by validating source integrity
// and using extractor-based seeking

Try / catch

try { extractor.read(input, seekPosition, output); }
catch (IOException e) {
  // log lastDecodePosition, advance input, continue extraction
}

Prevention

When it happens

Trigger: During readSample, decodeSampleWithBacktrackPosition throws FlacFrameDecodeException (see error 77) at lastDecodePosition; the extractor converts it to an IOException that surfaces to the extraction loop.

Common situations: Corrupt FLAC input being extracted; a seek landing on an invalid frame; network source providing truncated/garbled FLAC data; mid-stream bitstream errors.

Related errors


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/1c4555be4ddcaa61. Report an issue: GitHub.