laurent22/joplin · error · Error
No model found at path: ${JSON.stringify(modelFolderPath)}
Error message
No model found at path: ${JSON.stringify(modelFolderPath)} What it means
Thrown by the whisper provider's `build` when the model folder path passed in does not exist on disk. This is the first existence check before reading `config.json` or `model.bin`, guarding against a missing or partially extracted model bundle.
Source
Thrown at packages/app-mobile/services/voiceTyping/whisper.ts:249
modelLocalFilepath(),
whisper.getUuidPath(locale),
// Legacy model filepath
join(modelLocalDirectory(), 'whisper_tiny.onnx'),
];
for (const path of pathsToRemove) {
if (await shim.fsDriver().exists(path)) {
logger.info('Remove', path);
await shim.fsDriver().remove(path, { recursive: true });
}
}
},
getUuidPath: () => {
return join(dirname(modelLocalFilepath()), 'uuid');
},
build: async ({ modelPath: modelFolderPath, callbacks, locale }) => {
logger.debug('Creating Whisper session from path', modelFolderPath);
if (!await shim.fsDriver().exists(modelFolderPath)) throw new Error(`No model found at path: ${JSON.stringify(modelFolderPath)}`);
if (Setting.value('env') === Env.Dev) {
try {
await testWhisper();
} catch (error) {
logger.error('Testing error', error);
await shim.showErrorDialog(`Test failure: ${error}`);
}
}
const modelPath = join(modelFolderPath, 'model.bin');
const configJsonPath = join(modelFolderPath, 'config.json');
const configJson = JSON.parse(await shim.fsDriver().readFile(configJsonPath, 'utf-8'));
const config = new WhisperConfig(configJson);
if (!await shim.fsDriver().exists(modelPath)) {
throw new Error(`Model not found at path ${modelPath}`);
}View on GitHub (pinned to 2654b33620)
Solutions
- Call `VoiceTyping.download()` (or rely on `build`'s own `isDownloaded` check) before `build`.
- If the folder is missing unexpectedly, call `clearDownloads()` then `download()` to re-fetch.
- Check available storage before downloading; a full disk aborts the download.
Example fix
// before
await provider.build({ modelPath, callbacks, locale });
// after
if (!await shim.fsDriver().exists(modelPath)) {
await voiceTyping.download();
}
await provider.build({ modelPath, callbacks, locale }); Defensive patterns
Strategy: validation
Validate before calling
if (!await shim.fsDriver().exists(modelFolderPath)) {
logger.info('Model folder missing; downloading');
await voiceTyping.download();
}
await provider.build({ modelPath: modelFolderPath, callbacks, locale }); Type guard
null
Try / catch
try {
await provider.build({ modelPath, callbacks, locale });
} catch (error) {
if (/No model found at path/i.test(error.message)) {
await voiceTyping.clearDownloads();
await voiceTyping.download();
return provider.build({ modelPath, callbacks, locale });
}
throw error;
} Prevention
- Ensure download() completes before build().
- Run clearDownloads() then download() if the folder is unexpectedly absent.
- Check device free space before downloading.
When it happens
Trigger: Calling `whisper.build({ modelPath, ... })` where `modelPath` (a folder) does not exist — e.g. after `download()` failed silently, the cache was cleared, or `getModelPath()` returned a stale path.
Common situations: User cleared app cache; a previous download threw mid-stream and the folder was never created; the unzip step failed and cleaned up in its `finally`; storage migrated/changed between launches.
Related errors
- Model not found at path ${modelPath}
- No supported provider found!
- Error! Destination already exists
- No note with id ${id}
- The active profile cannot be deleted. Switch to a different
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/cf905585950480ce.
Report an issue: GitHub.