{"record":{"id":"6a394f832022a878","repo":"ruvnet/ruflo","slug":"cannot-compute-baseline-from-empty-readings","errorCode":null,"errorMessage":"Cannot compute baseline from empty readings","messagePattern":"Cannot compute baseline from empty readings","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/plugin-iot-cognitum/src/domain/services/anomaly-detection-service.ts","lineNumber":46,"sourceCode":"\nexport class AnomalyDetectionService {\n  private readonly config: AnomalyDetectionConfig;\n  private readonly baselines = new Map<string, TelemetryBaseline>();\n\n  constructor(config?: Partial<AnomalyDetectionConfig>) {\n    this.config = {\n      anomalyThreshold: config?.anomalyThreshold ?? 0.7,\n      quarantineThreshold: config?.quarantineThreshold ?? 0.9,\n      baselineWindowSize: config?.baselineWindowSize ?? 100,\n    };\n  }\n\n  /**\n   * Compute a baseline from a window of readings for a device.\n   * Calculates mean and standard deviation per vector dimension.\n   */\n  computeBaseline(deviceId: string, readings: TelemetryReading[]): TelemetryBaseline {\n    if (readings.length === 0) throw new Error('Cannot compute baseline from empty readings');\n\n    const dim = readings[0].vector.length;\n    const n = readings.length;\n\n    // Compute mean\n    const mean = new Array<number>(dim).fill(0);\n    for (const r of readings) {\n      for (let i = 0; i < dim; i++) mean[i] += r.vector[i] / n;\n    }\n\n    // Compute standard deviation\n    const std = new Array<number>(dim).fill(0);\n    for (const r of readings) {\n      for (let i = 0; i < dim; i++) {\n        const diff = r.vector[i] - mean[i];\n        std[i] += (diff * diff) / n;\n      }\n    }","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/plugin-iot-cognitum/src/domain/services/anomaly-detection-service.ts#L28-L64","documentation":"AnomalyDetectionService.computeBaseline derives per-dimension mean and standard deviation from a window of telemetry readings and needs at least one reading to establish dimensionality (readings[0].vector.length). An empty window is rejected up front rather than producing NaN statistics.","triggerScenarios":"Calling computeBaseline with an empty readings array — typically a device that just registered and has no telemetry yet, or a time-window/baselineWindowSize query that matched zero readings.","commonSituations":"Baselining immediately after device onboarding before any ingest; querying a window that starts before the device's first telemetry timestamp; devices that were offline and accumulated no readings.","solutions":["Ingest at least one telemetry vector for the device before computing a baseline","Guard the call: skip or defer baseline computation when readings.length === 0","Verify the window bounds of the query include the device's actual telemetry range"],"exampleFix":"// before\nconst baseline = svc.computeBaseline(deviceId, await fetchReadings(deviceId, window)); // [] -> throws\n\n// after\nconst readings = await fetchReadings(deviceId, window);\nif (readings.length === 0) {\n  logger.info(`no readings yet for ${deviceId}; baseline deferred`);\n} else {\n  const baseline = svc.computeBaseline(deviceId, readings);\n}","handlingStrategy":"validation","validationCode":"const readings = await fetchReadings(deviceId, window);\nif (readings.length === 0) {\n  return { status: 'deferred', reason: 'no readings in window' };\n}\nreturn svc.computeBaseline(deviceId, readings);","typeGuard":"function hasReadings(rs: TelemetryReading[]): rs is [TelemetryReading, ...TelemetryReading[]] {\n  return rs.length > 0;\n}","tryCatchPattern":"try {\n  svc.computeBaseline(deviceId, readings);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Cannot compute baseline from empty readings') {\n    // defer baseline until telemetry arrives\n  } else throw e;\n}","preventionTips":["Sequence onboarding as register, ingest, then baseline","Log per-window reading counts in telemetry pipelines","Alert on devices producing zero readings so baselines are never attempted on empty data"],"tags":["iot","statistics","validation","telemetry"],"backgroundTag":"empty-input-array","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"}