ruvnet/ruflo · error
Unknown hyperbolic model: ${this.model}
Error message
Unknown hyperbolic model: ${this.model} What it means
HyperbolicSpace.distance() dispatches on the model string to poincare/lorentz/klein/half_space formulas (hyperbolic.ts:305). The HyperbolicModel union has exactly those four members, so in typed TypeScript this is unreachable; at runtime any other string (typos, legacy names, unvalidated JSON config) falls through to the default branch and throws.
Source
Thrown at v3/@claude-flow/plugins/src/integrations/ruvector/hyperbolic.ts:305
* - Klein: Converted to Poincare first
* - Half-space: d(u,v) = arcosh(1 + ||u-v||^2 / (2*u_n*v_n))
*
* @param a - First point
* @param b - Second point
* @returns Geodesic distance
*/
distance(a: number[], b: number[]): number {
switch (this.model) {
case 'poincare':
return this.poincareDistance(a, b);
case 'lorentz':
return this.lorentzDistance(a, b);
case 'klein':
return this.kleinDistance(a, b);
case 'half_space':
return this.halfSpaceDistance(a, b);
default:
throw new Error(`Unknown hyperbolic model: ${this.model}`);
}
}
/**
* Computes distance in the Poincare ball model.
*
* Formula: d(u,v) = (2/sqrt|c|) * arctanh(sqrt|c| * ||(-u) +_M v||)
*
* Where +_M is Mobius addition.
*/
private poincareDistance(u: number[], v: number[]): number {
// Use Mobius addition: -u +_M v
const negU = scale(u, -1);
const diff = this.mobiusAdd(negU, v);
const diffNorm = norm(diff);
// d = (2/sqrt|c|) * arctanh(sqrt|c| * ||diff||)
const scaledNorm = this._scale * diffNorm;View on GitHub (pinned to fa13ee4ad6)
Solutions
- Use one of the four exact literals: 'poincare' | 'lorentz' | 'klein' | 'half_space'
- 'hyperboloid' maps to 'lorentz'; 'half-space'/'halfspace' map to 'half_space'
- Validate model strings at the boundary with a type guard before constructing the space
Example fix
// before
const space = new HyperbolicSpace('halfspace', -1); // typo
space.distance(a, b); // throws: Unknown hyperbolic model: halfspace
// after
const space = new HyperbolicSpace('half_space', -1);
space.distance(a, b); Defensive patterns
Strategy: type-guard
Validate before calling
const MODELS = ['poincare', 'lorentz', 'klein', 'half_space'] as const;
if (!MODELS.includes(cfg.model)) {
throw new TypeError(`model must be one of ${MODELS.join('|')}, got '${cfg.model}'`);
}
const space = new HyperbolicSpace(cfg.model, cfg.curvature); Type guard
const HYPERBOLIC_MODELS = new Set(['poincare', 'lorentz', 'klein', 'half_space']);
function isHyperbolicModel(v: unknown): v is HyperbolicModel {
return typeof v === 'string' && HYPERBOLIC_MODELS.has(v);
} Try / catch
try {
const d = space.distance(a, b);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Unknown hyperbolic model')) {
throw new ConfigError(`Fix the model name: ${err.message}`); // config bug, do not retry
}
throw err;
} Prevention
- Type all model inputs as HyperbolicModel and validate at the config boundary
- Common aliases: 'hyperboloid' -> 'lorentz', 'half-space'/'halfspace' -> 'half_space'
- Smoke-test constructed spaces (one distance call) at startup so bad models fail early
When it happens
Trigger: Constructing HyperbolicSpace with model 'halfspace' (missing underscore), 'Poincare' (capitalized), 'hyperboloid' (the concept's other name for lorentz), or a value read from env/JSON/database without validation, then calling distance(a, b).
Common situations: Config files authored from memory of the literature ('hyperboloid', 'half-space' with a hyphen); deserializing spaces persisted by older versions; JS consumers bypassing the TypeScript union.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid completion type
- piiPolicy must be one of: ${PII_POLICIES.join(', ')}
- mode must be legacy, observe, or enforce
- Embedding must be Float32Array of length ${this.dimension}
- Training system not initialized
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/b17bbf2e15a0a572.
Report an issue: GitHub.