{"record":{"id":"00543c078f14327e","repo":"ruvnet/ruflo","slug":"cannot-calibrate-with-empty-samples","errorCode":null,"errorMessage":"Cannot calibrate with empty samples","messagePattern":"Cannot calibrate with empty samples","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/plugins/src/integrations/ruvector/quantization.ts","lineNumber":331,"sourceCode":"      maxValue: options.maxValue ?? 1,\n      scale: 1,\n      zeroPoint: 0,\n    };\n\n    if (options.minValue !== undefined && options.maxValue !== undefined) {\n      this.computeCalibration(options.minValue, options.maxValue);\n      this.isCalibrated = true;\n    }\n  }\n\n  /**\n   * Calibrates the quantizer using sample vectors.\n   *\n   * @param samples - Representative vectors for calibration\n   */\n  calibrate(samples: number[][]): void {\n    if (samples.length === 0) {\n      throw new Error('Cannot calibrate with empty samples');\n    }\n\n    // Find min and max across all dimensions and samples\n    let minValue = Infinity;\n    let maxValue = -Infinity;\n\n    for (const sample of samples) {\n      for (let i = 0; i < sample.length; i++) {\n        minValue = Math.min(minValue, sample[i]);\n        maxValue = Math.max(maxValue, sample[i]);\n      }\n    }\n\n    // Add small margin for numerical stability\n    const range = maxValue - minValue;\n    minValue -= range * 0.01;\n    maxValue += range * 0.01;\n","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/plugins/src/integrations/ruvector/quantization.ts#L313-L349","documentation":"ScalarQuantizer.calibrate() (quantization.ts:331) derives minValue/maxValue by scanning sample vectors, so at least one sample is required; an empty array throws. Calibration is optional — the constructor already calibrates when minValue/maxValue are passed explicitly — and calibrate() marks the quantizer isCalibrated.","triggerScenarios":"quantizer.calibrate([]) after a sampling step filtered out all rows (e.g. empty table, WHERE clause matching nothing, warmup before data lands); passing a training split that is empty due to a shuffling bug.","commonSituations":"New deployments pointing at an empty database; calibration jobs racing data ingestion; filters on embedding metadata removing every candidate.","solutions":["Skip or defer calibration when samples.length === 0","Pass explicit minValue/maxValue to the constructor instead of calibrating (e.g. -1/1 for normalized embeddings)","Log the sample count before calibrating so empty inputs are visible in ops"],"exampleFix":"// before\nquantizer.calibrate(await sampleEmbeddings()); // throws on empty table\n\n// after\nconst samples = await sampleEmbeddings();\nif (samples.length > 0) {\n  quantizer.calibrate(samples);\n} else {\n  logger.warn('Skipping calibration: no samples yet');\n}","handlingStrategy":"validation","validationCode":"if (samples.length === 0) {\n  throw new Error(`Calibration requires samples, got 0 (source: ${source})`);\n}\nquantizer.calibrate(samples);","typeGuard":"function isNonEmptySamples(v: number[][]): v is [number[], ...number[][]] {\n  return Array.isArray(v) && v.length > 0;\n}","tryCatchPattern":"try {\n  quantizer.calibrate(samples);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Cannot calibrate with empty samples') {\n    // keep constructor defaults (minValue/maxValue) and retry once data arrives\n    logger.warn('Calibration skipped: no samples');\n  } else throw err;\n}","preventionTips":["Pass explicit minValue/maxValue to the ScalarQuantizer constructor when the value range is known (e.g. -1/1)","Check row counts before running calibration jobs against the database","Run calibration after ingestion reaches a threshold, not on a cold start"],"tags":["quantization","calibration","empty-input","validation"],"backgroundTag":"empty-training-data","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"}