ruvnet/ruflo · error
Model " " not found. Available
Error message
Model "${name}" not found. Available: ${[...this.models.keys()].join(', ')} What it means
loadModel(name) looks the name up in a Map that initialize() populates by scanning modelsDir for GGUF model files. The throw embeds the list of discovered names, so the mismatch is usually visible in the message itself: the requested name is not a discovered .gguf model — either a naming mismatch or nothing was discovered at all (initialize not run / wrong directory).
Solutions
- Ensure `await bridge.initialize()` has completed before calling loadModel
- Inspect `await bridge.listModels()` and use an exact name from that result (the error message's Available list is the same data)
- Verify the .gguf file actually exists under the configured modelsDir
- If the Available list is empty, fix modelsDir (see RuvllmConfig.modelsDir is required) or download models into it
Example fix
// before
await bridge.loadModel('llama3'); // Model "llama3" not found. Available: llama-3-8b.Q4_K_M.gguf
// after
await bridge.initialize();
const target = (await bridge.listModels()).find(m => m.name.startsWith('llama-3'));
if (!target) throw new Error('No llama-3 model found — download one into modelsDir first');
await bridge.loadModel(target.name); Defensive patterns
Strategy: validation
Validate before calling
await bridge.initialize();
const available = new Set((await bridge.listModels()).map(m => m.name));
if (!available.has(requestedName)) {
throw new Error(`Unknown model "${requestedName}". Known: ${[...available].join(', ')}`);
}
await bridge.loadModel(requestedName); Try / catch
try {
await bridge.loadModel(name);
} catch (e) {
if (e instanceof Error && e.message.includes('not found. Available:')) {
// initialize() may not have run, or the name is stale — re-list and pick an exact match
const models = await bridge.listModels();
const match = models.find(m => m.name.includes(name));
if (!match) throw e;
await bridge.loadModel(match.name);
} else {
throw e;
}
} Prevention
- Always await initialize() and drive model selection from listModels() output rather than hardcoded names
- Log discovered models at startup so an empty modelsDir is caught immediately
- Match on file names (e.g. llama-3-8b.Q4_K_M.gguf), not marketing names
When it happens
Trigger: Calling `bridge.loadModel(name)` before `await bridge.initialize()` (map empty, 'Available:' lists nothing); passing a display name that differs from the discovered file name; modelsDir containing no .gguf files; modelsDir pointing at the wrong folder.
Common situations: User asks for 'llama3' but the file is 'llama-3-8b.Q4_K_M.gguf'; model files renamed or moved on disk; initialize() silently discovered zero models because the configured directory is empty or wrong.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/6c57983de136ebfb.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/appliance/ruvllm-bridge.ts:182
this.ruvectorCore && '@ruvector/core',
this.ruvectorRouter && '@ruvector/router',
this.ruvectorSona && '@ruvector/sona',
this.ggufEngine && 'gguf-engine',
].filter(Boolean);
if (pkgs.length) console.log(`[ruvLLM] Loaded: ${pkgs.join(', ')}`);
console.log(`[ruvLLM] ${this.models.size} model(s) in ${this.config.modelsDir}`);
}
}
/** Return all discovered GGUF models. */
async listModels(): Promise<ModelInfo[]> {
return Array.from(this.models.values());
}
/** Load a model into memory (delegates to GGUF engine or @ruvector/core). */
async loadModel(name: string): Promise<void> {
const info = this.models.get(name);
if (!info) throw new Error(`Model "${name}" not found. Available: ${[...this.models.keys()].join(', ')}`);
// Prefer GGUF engine (parses header, loads via node-llama-cpp if available)
if (this.ggufEngine) {
const meta = await this.ggufEngine.loadModel(info.path);
if (meta.architecture) info.parameters = meta.architecture;
if (meta.quantization) info.quantization = meta.quantization;
} else if (this.ruvectorCore?.loadModel) {
await this.ruvectorCore.loadModel(info.path, { contextSize: this.config.contextSize });
}
info.loaded = true;
this.activeModel = name;
}
/**
* Generate text from a prompt. Routes through tiers:
* 1. Agent Booster (trivial transforms, no LLM).
* 2. Local GGUF model via @ruvector/core.
* 3. Cloud fallback (empty response -- caller handles upstream).View on GitHub (pinned to fa13ee4ad6)