{"record":{"id":"b17bbf2e15a0a572","repo":"ruvnet/ruflo","slug":"unknown-hyperbolic-model-this-model","errorCode":null,"errorMessage":"Unknown hyperbolic model: ${this.model}","messagePattern":"Unknown hyperbolic model: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/plugins/src/integrations/ruvector/hyperbolic.ts","lineNumber":305,"sourceCode":"   * - Klein: Converted to Poincare first\n   * - Half-space: d(u,v) = arcosh(1 + ||u-v||^2 / (2*u_n*v_n))\n   *\n   * @param a - First point\n   * @param b - Second point\n   * @returns Geodesic distance\n   */\n  distance(a: number[], b: number[]): number {\n    switch (this.model) {\n      case 'poincare':\n        return this.poincareDistance(a, b);\n      case 'lorentz':\n        return this.lorentzDistance(a, b);\n      case 'klein':\n        return this.kleinDistance(a, b);\n      case 'half_space':\n        return this.halfSpaceDistance(a, b);\n      default:\n        throw new Error(`Unknown hyperbolic model: ${this.model}`);\n    }\n  }\n\n  /**\n   * Computes distance in the Poincare ball model.\n   *\n   * Formula: d(u,v) = (2/sqrt|c|) * arctanh(sqrt|c| * ||(-u) +_M v||)\n   *\n   * Where +_M is Mobius addition.\n   */\n  private poincareDistance(u: number[], v: number[]): number {\n    // Use Mobius addition: -u +_M v\n    const negU = scale(u, -1);\n    const diff = this.mobiusAdd(negU, v);\n    const diffNorm = norm(diff);\n\n    // d = (2/sqrt|c|) * arctanh(sqrt|c| * ||diff||)\n    const scaledNorm = this._scale * diffNorm;","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/plugins/src/integrations/ruvector/hyperbolic.ts#L287-L323","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nconst space = new HyperbolicSpace('halfspace', -1); // typo\nspace.distance(a, b); // throws: Unknown hyperbolic model: halfspace\n\n// after\nconst space = new HyperbolicSpace('half_space', -1);\nspace.distance(a, b);","handlingStrategy":"type-guard","validationCode":"const MODELS = ['poincare', 'lorentz', 'klein', 'half_space'] as const;\nif (!MODELS.includes(cfg.model)) {\n  throw new TypeError(`model must be one of ${MODELS.join('|')}, got '${cfg.model}'`);\n}\nconst space = new HyperbolicSpace(cfg.model, cfg.curvature);","typeGuard":"const HYPERBOLIC_MODELS = new Set(['poincare', 'lorentz', 'klein', 'half_space']);\nfunction isHyperbolicModel(v: unknown): v is HyperbolicModel {\n  return typeof v === 'string' && HYPERBOLIC_MODELS.has(v);\n}","tryCatchPattern":"try {\n  const d = space.distance(a, b);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Unknown hyperbolic model')) {\n    throw new ConfigError(`Fix the model name: ${err.message}`); // config bug, do not retry\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["hyperbolic-geometry","enum","invalid-value","ruvector"],"backgroundTag":"invalid-enum-value","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}