SubtitleEdit/subtitleedit · error · InvalidOperationException

No PGS subtitles in MKV track #{track.TrackNumber}.

Error message

No PGS subtitles in MKV track #{track.TrackNumber}.

What it means

InvalidOperationException from LoadMatroskaPgs: parsing the selected MKV track as PGS yielded zero PCS entries. The track was identified as S_HDMV/PGS but its blocks did not decode into any presentation composition segments.

Source

Thrown at src/seconv/Core/BitmapSubtitleLoader.cs:67

        var log = new StringBuilder();
        var pcsList = BluRaySupParser.ParseBluRaySup(filePath, log);
        if (pcsList.Count == 0)
        {
            throw new InvalidOperationException($"No Blu-Ray sup subtitles found in: {filePath}");
        }
        return PcsListToItems(pcsList);
    }

    /// <summary>
    /// MKV PGS track (S_HDMV/PGS) → bitmap events. PGS-in-MKV is the same PCS payload
    /// as a .sup file, just wrapped in Matroska block timing.
    /// </summary>
    public static IReadOnlyList<BitmapSubtitleItem> LoadMatroskaPgs(MatroskaFile matroska, MatroskaTrackInfo track)
    {
        var pcsList = BluRaySupParser.ParseBluRaySupFromMatroska(track, matroska);
        if (pcsList.Count == 0)
        {
            throw new InvalidOperationException($"No PGS subtitles in MKV track #{track.TrackNumber}.");
        }
        return PcsListToItems(pcsList);
    }

    /// <summary>
    /// VobSub <c>.sub</c> (+ optional <c>.idx</c>) → bitmap events. Uses
    /// <see cref="VobSubParser.OpenSubIdx"/>, which uses the .idx for timing + palette when
    /// present and otherwise parses the .sub's MPEG-PS stream directly (stream PTS timing +
    /// a default palette). The frame size comes from the .idx's <c>size:</c> line when it has
    /// one — VobSub is not always DVD-sized (Subtitle Edit's own export writes whatever the
    /// source was, e.g. <c>size: 1920x1080</c>) and squeezing a 1920x1080 stream into a DVD
    /// frame moves every subpicture. Without that line, fall back to the DVD standards
    /// (720x576 PAL, 720x480 NTSC) rather than <c>--resolution</c> / 1920x1080.
    /// </summary>
    public static IReadOnlyList<BitmapSubtitleItem> LoadVobSub(string subPath, string idxPath, bool isPal)
    {
        var parser = new VobSubParser(isPal);
        // OpenSubIdx falls back to parsing the .sub stream directly when the .idx is missing,

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Enumerate tracks and select one whose CodecID/TrackCodec is S_HDMV/PGS before calling LoadMatroskaPgs.
  2. Inspect tracks with mkvinfo or ffprobe to confirm which track number holds the PGS stream.
  3. If the track is actually VobSub, call LoadMatroskaVobSub instead.

Example fix

// before
if (pcsList.Count == 0)
    throw new InvalidOperationException($"No PGS subtitles in MKV track #{track.TrackNumber}.");

// after
if (pcsList.Count == 0)
    throw new InvalidOperationException($"No PGS subtitles in MKV track #{track.TrackNumber} (codec: {track.CodecID}). Pick an S_HDMV/PGS track.");
Defensive patterns

Strategy: validation

Validate before calling

if (!string.Equals(track.CodecID, "S_HDMV/PGS", StringComparison.OrdinalIgnoreCase))
    throw new InvalidOperationException($"Track #{track.TrackNumber} is {track.CodecID}, not PGS. Pick an S_HDMV/PGS track.");

Type guard

static bool IsPgsTrack(MatroskaTrackInfo t) => string.Equals(t.CodecID, "S_HDMV/PGS", StringComparison.OrdinalIgnoreCase);

Try / catch

null

Prevention

When it happens

Trigger: Passing the wrong track.TrackNumber to LoadMatroskaPgs — e.g. an audio track, a VobSub track, or an empty PGS track — so ParseBluRaySupFromMatroska returns an empty list.

Common situations: Caller enumerated MKV tracks but indexed by position rather than by codec ID; the chosen track is actually S_VOBSUB; PGS track is present but has no events.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/f46076014b359259. Report an issue: GitHub.