remotion-dev/remotion · error · Error

Invalid channel index ${channelIndex} for audio with ${audio

Error message

Invalid channel index ${channelIndex} for audio with ${audioTrack.numberOfChannels} channels

What it means

Thrown inside useWindowedAudioData() when the requested channelIndex is out of range for the decoded audio track (line 156-160). The guard fires when channelIndex >= audioTrack.numberOfChannels or channelIndex < 0, and the message reports both the requested index and the actual channel count. Forwarded to cancelRender(), failing the render.

Source

Thrown at packages/media-utils/src/use-windowed-audio-data.ts:157

							src,
					);
				}

				if (await audioTrack.isRelativeToUnixEpoch()) {
					throw new Error(
						'Streams with UNIX timestamps are not currently supported by Remotion. Sorry! Source: ' +
							src,
					);
				}

				const canDecode = await audioTrack.canDecode();

				if (!canDecode) {
					throw new Error('Audio track cannot be decoded');
				}

				if (channelIndex >= audioTrack.numberOfChannels || channelIndex < 0) {
					throw new Error(
						`Invalid channel index ${channelIndex} for audio with ${audioTrack.numberOfChannels} channels`,
					);
				}

				const numberOfChannels = await audioTrack.getNumberOfChannels();
				const sampleRate = await audioTrack.getSampleRate();

				const format = await input.getFormat();

				const isMatroska = format === MATROSKA || format === WEBM;

				if (isMounted.current) {
					setAudioUtils({
						input,
						track: audioTrack,
						metadata: {
							durationInSeconds,
							numberOfChannels,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Default channelIndex to 0 (mono-safe) unless you specifically need another channel, and clamp it to the actual track's numberOfChannels - 1.
  2. Probe the asset's channel count first (ffprobe or Mediabunny) and pass a valid index based on that value.
  3. For visualizations that need a specific channel, require/prefer stereo assets or fall back to channel 0 when fewer channels exist.
  4. Add a runtime guard at the call site so an invalid index never reaches the hook.

Example fix

// before (stereo-only code on a mono asset -> throws)
useWindowedAudioData({src, channelIndex: 1, ...});

// after (clamp to available channels before passing)
const channels = await getAudioNumberOfChannels(src);
const channelIndex = Math.min(1, Math.max(0, channels - 1));
useWindowedAudioData({src, channelIndex, ...});
Defensive patterns

Strategy: validation

Validate before calling

// Clamp channelIndex to the asset's actual channel count before calling the hook
import {execFileSync} from 'child_process';

function getNumberOfAudioChannels(file: string): number {
  const n = execFileSync('ffprobe', ['-v', 'error', '-select_streams', 'a:0', '-show_entries', 'stream=channels', '-of', 'csv=p=0', file], {encoding: 'utf8'}).trim();
  return Number(n) || 1;
}

const channels = getNumberOfAudioChannels(file);
const safeChannelIndex = Math.min(requestedChannel, Math.max(0, channels - 1));

Type guard

function isValidChannelIndex(index: number, channels: number): boolean {
  return Number.isInteger(index) && index >= 0 && index < channels;
}

Try / catch

// Forwarded to cancelRender(); wrap an ErrorBoundary and fall back to channel 0:
// <ErrorBoundary fallback={<Waveform channelIndex={0} ... />}>
//   <WindowedWaveform channelIndex={requested} ... />
// </ErrorBoundary>

Prevention

When it happens

Trigger: Requesting channelIndex 1 (right) on a mono asset; requesting channel 5 on a stereo asset; passing -1 to mean 'auto'; defaulting to a high channel index without checking the source; passing a 0-based index when the source only has 1 channel.

Common situations: Hard-coding channelIndex for a stereo visualization on a mono voiceover; letting a user pick a channel without clamping; copying example code that uses channelIndex 1 onto a mono recording; assets that were downmixed to mono during export without updating the component.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/3ba0ae23db72fc7c. Report an issue: GitHub.