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

  1. Ensure `await bridge.initialize()` has completed before calling loadModel
  2. Inspect `await bridge.listModels()` and use an exact name from that result (the error message's Available list is the same data)
  3. Verify the .gguf file actually exists under the configured modelsDir
  4. 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

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)