AttributeError: 'generator' object has no attribute 'info'
builtins.AttributeError (faster-whisper WhisperModel.transcribe return type mismatch)
Stack trace
Traceback (most recent call last):
File "transcribe.py", line 12, in <module>
segments, info = model.transcribe(audio_path)
info_dict = segments.info
AttributeError: 'generator' object has no attribute 'info'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "transcribe.py", line 15, in <module>
print(segments.info['vad_options'])
AttributeError: 'generator' object has no attribute 'info' Why it happens
faster-whisper>=0.9.0 changed WhisperModel.transcribe() to return a tuple of (generator<Segment>, dict) instead of (list<Segment>, dict). Unpacking with segments, info = model.transcribe(...) assigns the generator to segments, not a list. Code that tries to access .info on segments fails because generators don't have an info attribute: info is the second element of the tuple that gets ignored. This is a common pattern breakage when upgrading faster-whisper.
Detection
Before iterating segments, verify the return type with isinstance(segments, types.GeneratorType). If True, you're receiving a generator; info will be in a separate variable from unpacking. Log both segments (first element) and info (second element) separately to catch this mismatch immediately.
Causes & fixes
Unpacking model.transcribe() result into only two variables when generator is returned
Use tuple unpacking explicitly: segments, info = model.transcribe(audio_path) correctly unpacks both. Then iterate: for segment in segments: ... and access info dict separately with info['vad_options'], etc.
Trying to access .info attribute directly on the generator object instead of unpacked tuple
Store unpacked values in separate variables: segments_gen, info = model.transcribe(audio); then access info['key']: not segments_gen.info, which doesn't exist.
Assigning model.transcribe() result to single variable and iterating it
Never do result = model.transcribe(...); for seg in result. Instead: segments, info = model.transcribe(...); for seg in segments.
Using deprecated faster-whisper API that returned (list, dict): code expects old behavior
Verify faster-whisper version >= 0.9.0. If upgrading from <0.9.0, refactor unpacking: the tuple structure is unchanged, but the first element is now a generator, not a list: iteration works the same way.
Code: broken vs fixed
import faster_whisper
import os
model = faster_whisper.WhisperModel('base', device='cpu')
audio_path = 'sample_audio.mp3'
# BROKEN: Trying to access .info on the generator
segments = model.transcribe(audio_path) # Returns (generator, dict) but assigns only generator
print(segments.info) # ❌ AttributeError: 'generator' object has no attribute 'info'
# Or worse: unpacking into wrong variable
result = model.transcribe(audio_path)
for segment in result: # ❌ Tries to iterate tuple, not generator
print(segment.text)
print(result.info) # ❌ AttributeError: 'tuple' object has no attribute 'info' import faster_whisper
import os
model = faster_whisper.WhisperModel('base', device='cpu')
audio_path = 'sample_audio.mp3'
# FIXED: Unpack the tuple correctly into (generator, dict)
segments, info = model.transcribe(audio_path) # ✅ Correct unpacking
print(f"Language: {info['language']}") # ✅ Access info dict
print(f"Duration: {info['duration']}") # ✅ info is a dict, not accessed on generator
# Iterate the generator
for segment in segments:
print(f"[{segment.start:.2f}s - {segment.end:.2f}s] {segment.text}")
# Optional: Convert generator to list for random access (if needed for specific use case)
segments_list = list(segments) # ✅ Now you can index: segments_list[0]
print(f"Total segments: {len(segments_list)}")
print(f"First segment: {segments_list[0].text}") Workaround
If code is embedded deep and refactoring is risky, convert the generator to a list immediately after unpacking: segments, info = model.transcribe(...); segments = list(segments). Then the segments variable behaves like the old API (list of Segment objects), and info remains accessible as a dict. Performance cost is minimal for typical audio files (1–5 min duration).
Prevention
Always unpack faster-whisper.WhisperModel.transcribe() into exactly two variables at the call site. Never assign the return value to a single variable. Add a type assertion in development: `assert isinstance(segments, types.GeneratorType) or isinstance(segments, list)` and `assert isinstance(info, dict)` right after unpacking to catch version mismatches early. Document the return type in code comments: `# Returns: (generator[Segment], dict[str, Any])`.