ruvnet/ruflo · error · Error
Invalid embedding model name
Error message
Invalid embedding model name: ${embeddingModel} What it means
Thrown by `claude-flow init --with-embeddings` when --embedding-model does not match ^[a-zA-Z0-9_-]+/[a-zA-Z0-9._-]+$. The string is later passed to an npx invocation (in some configurations via cmd.exe on Windows), so it is restricted to a strict Hugging Face-style org/model identifier as CRIT-02 command-injection hardening. Validation happens before any child process spawns.
Solutions
- Omit the flag — the default Xenova/all-MiniLM-L6-v2 always passes validation
- Pass a plain org/model id, e.g. --embedding-model Xenova/all-MiniLM-L6-v2 or BAAI/bge-small-en-v1.5
- Strip @revision and :tag suffixes from the identifier before passing it
Example fix
# before claude-flow init --with-embeddings --embedding-model minilm-l6 # after claude-flow init --with-embeddings --embedding-model Xenova/all-MiniLM-L6-v2
Defensive patterns
Strategy: validation
Validate before calling
const EMBEDDING_MODEL_RE = /^[a-zA-Z0-9_-]+\/[a-zA-Z0-9._-]+$/;
if (!EMBEDDING_MODEL_RE.test(embeddingModel)) {
throw new Error(`Bad model id: ${embeddingModel} (expected org/model)`);
}
await cli.init({ withEmbeddings: true, embeddingModel }); Type guard
function isValidEmbeddingModelId(v: unknown): v is string {
return typeof v === 'string' && /^[a-zA-Z0-9_-]+\/[a-zA-Z0-9._-]+$/.test(v);
} Prevention
- Store model ids as strict org/model strings in config, never free-form text
- Strip @revision and :tag suffixes at the source that produces the value
- Default to Xenova/all-MiniLM-L6-v2 instead of asking users to type one
When it happens
Trigger: Passing --embedding-model all-MiniLM-L6-v2 (missing org), Xenova/all-MiniLM-L6-v2@refs/pr/2 (@ not allowed), 'Xenova / model' (spaces), or org/model:revision (colon rejected), together with --with-embeddings on init.
Common situations: Using Docker-style tag syntax (model:latest), pasting a Hugging Face URL instead of the repo id, or copying a model@revision pin from docs into the flag.
Related errors
- each record requires a non-empty numeric vector
- Embedding must be Float32Array of length
- Invalid container name
- Invalid embedding value at index
- loop run requires a prompt unless --command is provided
AI-assisted analysis of ruvnet/ruflo@5234333c34 (2026-08-18).
Data as JSON: /api/errors/48e2a09a8ec70909.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/commands/init.ts:835
}
output.writeln();
output.printSuccess('All services started');
}
// Handle --with-embeddings
const withEmbeddings = ctx.flags['with-embeddings'] || ctx.flags.withEmbeddings;
const embeddingModel = (ctx.flags['embedding-model'] || ctx.flags.embeddingModel || 'Xenova/all-MiniLM-L6-v2') as string;
if (withEmbeddings) {
output.writeln();
output.printInfo('Initializing ONNX embedding subsystem...');
const { execFileSync: execFileInit } = await import('child_process');
// Validate embeddingModel: must match pattern org/model-name (CRIT-02)
if (!/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9._-]+$/.test(embeddingModel)) {
throw new Error(`Invalid embedding model name: ${embeddingModel}`);
}
try {
output.writeln(output.dim(` Model: ${embeddingModel}`));
output.writeln(output.dim(' Hyperbolic: Enabled (Poincaré ball)'));
// #2770: On Windows, `npx` ships as `npx.cmd`; execFileSync cannot spawn
// a .cmd file without going through cmd.exe. Enable shell on win32 so
// cmd.exe resolves the .cmd extension. POSIX keeps shell:false.
// NOTE: shell:true joins args by spaces and passes to cmd.exe — the args
// here are hard-coded flags + an npm package name pre-validated against
// /^[a-zA-Z0-9_-]+\/[a-zA-Z0-9._-]+$/, so no injection risk. If
// user-controlled args are ever added, escape them before spawn.
execFileInit('npx', [
'@claude-flow/cli@latest', 'embeddings', 'init',
'--model', embeddingModel,
'--no-download', '--force',
], {
stdio: 'pipe',View on GitHub (pinned to 5234333c34)