mifi/lossless-cut · error · UserFacingError
No VTS vob files found in folder
Error message
No VTS vob files found in folder
What it means
Thrown by readVideoTs() when, after reading the directory and filtering for files matching ^vts_\d+_\d+\.vob$ (case-insensitive) while excluding ^vts_\d+_00\.vob$ menu VOBs, the result list is empty. The function exists to gather the playable VTS (Video Title Set) VOBs of a DVD VIDEO_TS folder, so an empty result means this is not a usable DVD structure.
Source
Thrown at src/renderer/src/util.ts:377
if (working) {
if (progress != null) parts.push(`${(progress * 100).toFixed(1)}%`);
parts.push(working);
}
if (filePath) {
parts.push(basename(filePath));
}
parts.push(isStoreBuild ? appName : `${appName} ${appVersion}`);
document.title = parts.join(' - ');
}
export async function readVideoTs(videoTsPath: string) {
const files = await readdir(videoTsPath);
const relevantFiles = files.filter((file) => /^vts_\d+_\d+\.vob$/i.test(file) && !/^vts_\d+_00\.vob$/i.test(file)); // skip menu
const ret = sortBy(relevantFiles).map((file) => join(videoTsPath, file));
if (ret.length === 0) throw new UserFacingError(i18n.t('No VTS vob files found in folder'));
return ret;
}
export async function readDirRecursively(dirPath: string) {
const files = await readdir(dirPath, { recursive: true });
const ret = (await pMap(files, async (path) => {
if (['.DS_Store'].includes(basename(path))) return [];
const absPath = join(dirPath, path);
const fileStat = await lstat(absPath); // readdir also returns directories...
if (!fileStat.isFile()) return [];
return [absPath];
}, { concurrency: 5 })).flat();
if (ret.length === 0) throw new UserFacingError(i18n.t('No files found in folder'));
return ret;
}View on GitHub (pinned to 3b9a59c288)
Solutions
- Confirm the folder is a real DVD VIDEO_TS directory containing VTS_01_1.VOB, VTS_01_2.VOB, etc.
- Re-rip the DVD with a tool that produces the full VTS title VOBs, not just menus.
- Point the open-folder dialog at the exact VIDEO_TS folder, not its parent.
- If only a single VOB is needed, open the .vob file directly rather than via the DVD folder path.
Defensive patterns
Strategy: validation
Validate before calling
import { readdir } from 'fs/promises';
export async function hasVtsVobs(videoTsPath: string): Promise<boolean> {
const files = await readdir(videoTsPath);
return files.some((f) => /^vts_\d+_\d+\.vob$/i.test(f) && !/^vts_\d+_00\.vob$/i.test(f));
}
if (!(await hasVtsVobs(folder))) showError('Not a DVD VIDEO_TS folder with title VOBs.'); Try / catch
try {
return await readVideoTs(videoTsPath);
} catch (err) {
if (err instanceof UserFacingError && /No VTS vob files/.test(err.message)) {
showError('The selected folder has no DVD title VOBs.');
return [];
}
throw err;
} Prevention
- Point the dialog at the exact VIDEO_TS folder containing VTS_*_[1-9].VOB files.
- Verify a complete DVD rip (not just menus/IFOs) before opening.
- For single-VOB needs, open the .vob file directly instead of the folder.
When it happens
Trigger: Calling readVideoTs(dir) on a folder that contains no VTS_*_*.VOB files; pointing at a VIDEO_TS folder that only has menu VOBs (VTS_xx_00.VOB); selecting a regular folder that merely happens to be named VIDEO_TS but holds no DVD content.
Common situations: User selects the wrong folder (the parent of VIDEO_TS, or a BUP/IFO-only folder); an incompletely ripped DVD missing the title VOBs; a folder containing only the menu/title set metadata; a non-DVD folder passed to the DVD-open path.
Related errors
- No files found in folder
- No rows found
- Invalid start or end value. Must contain a number of seconds
- Invalid EDL data found
- Less than 2 frames found
AI-assisted analysis of mifi/lossless-cut@3b9a59c288 (2026-08-12).
Data as JSON: /api/errors/7625c2cb15dd9ccd.
Report an issue: GitHub.