SubtitleEdit/subtitleedit · error · InvalidOperationException
VobSub '.idx' input has no companion '.sub' ({Path.GetFileNa
Error message
VobSub '.idx' input has no companion '.sub' ({Path.GetFileName(subPath)}) — the .idx only holds timing and palette; the subtitle images live in the .sub. What it means
Thrown by ContainerSubtitleLoader when the input file has a .idx extension but no companion .sub exists beside it (Path.ChangeExtension to .sub yields a non-existent file). A VobSub .idx only holds timing and palette metadata; the actual subtitle images live in the .sub, so the conversion cannot proceed without it. The redirect from .idx to .sub preserves the 5.0.0 behaviour documented against issue #12772.
Source
Thrown at src/seconv/Core/ContainerSubtitleLoader.cs:112
{
AnsiConsole.MarkupLine(
$"[yellow]Note: VobSub '.sub' has no '.idx' companion ({Path.GetFileName(idxPath).EscapeMarkup()}); "
+ "reading timing from the stream and using a default color palette.[/]");
return LoadVobSub(filePath, idxPath, options);
}
return null;
}
if (ext == ".idx")
{
// 5.0.0 accepted the .idx of a VobSub pair as the input file; keep that working
// by redirecting to the companion .sub (which holds the actual subpictures) and
// using the given .idx for timing + palette (issue #12772).
var subPath = Path.ChangeExtension(filePath, ".sub");
if (!File.Exists(subPath))
{
throw new InvalidOperationException(
$"VobSub '.idx' input has no companion '.sub' ({Path.GetFileName(subPath)}) — "
+ "the .idx only holds timing and palette; the subtitle images live in the .sub.");
}
return LoadVobSub(subPath, filePath, options);
}
if (ext is ".ts" or ".m2ts" or ".mts")
{
return LoadTransportStream(filePath, options);
}
if (ext == ".mxf")
{
return LoadMxf(filePath, options);
}
return null;View on GitHub (pinned to 17a9f07487)
Solutions
- Locate the matching .sub file and place it next to the .idx with the same basename.
- Pass the .sub path directly instead of the .idx (the loader pairs them automatically when both exist).
- On case-sensitive filesystems, ensure the .sub extension matches exactly, or rename to lowercase .sub.
Example fix
// before: only movie.idx present seconv movie.idx -o out.srt // after: provide the companion .sub seconv movie.sub -o out.srt # .idx is auto-detected beside it
Defensive patterns
Strategy: validation
Validate before calling
// Validate the .idx/.sub pair exists before invoking the loader.
if (Path.GetExtension(filePath).Equals(".idx", StringComparison.OrdinalIgnoreCase))
{
var subPath = Path.ChangeExtension(filePath, ".sub");
if (!File.Exists(subPath))
return Error($"Missing companion .sub next to {filePath}");
} Try / catch
try { return ContainerSubtitleLoader.TryLoadTracks(filePath, options); }
catch (InvalidOperationException ex) when (ex.Message.Contains("companion '.sub"))
{ Console.Error.WriteLine(ex.Message); return null; } Prevention
- Before converting, confirm both the .idx and .sub of a VobSub pair exist in the same directory.
- Pass the .sub as input rather than the .idx to make the dependency explicit.
- On case-sensitive filesystems, keep extensions lowercase (.sub) to match Path.ChangeExtension output.
When it happens
Trigger: Invoking TryLoadTracks(filePath, options) (or the CLI) with a path ending in .idx where the sibling .sub (same basename, same directory) is absent — File.Exists(subPath) at line 110 returns false.
Common situations: User selects only the .idx of a VobSub pair; the .sub was deleted or never copied alongside; case-sensitivity on Linux where the file is .SUB but ChangeExtension produces .sub; pointing the tool at a lone .idx downloaded without its pair.
Related errors
- No subtitles recognised in VobSub file: {subPath}
- VobSub '.idx' input has no companion '.sub' ({Path.GetFileNa
- No VobSub subtitles in MKV track #{track.TrackNumber}.
- No VobSub subpictures found in MP4 track.
- Unable to access bitmap pixel data.
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/7d392fa7f1fda1ae.
Report an issue: GitHub.