affaan-m/ECC · error · Error

sampleIntervalMs must be positive and finite

Error message

sampleIntervalMs must be positive and finite

What it means

createControlPlaneViewSource validates its sampleIntervalMs dependency: if provided it must be a finite number greater than zero. The interval controls how long cached control-plane snapshots live before a refresh; a zero, negative, or non-numeric value would break the caching/expiry logic, so it is rejected at construction time.

Solutions

  1. Pass a positive finite number, e.g. sampleIntervalMs: 5000
  2. Convert config values with Number()/parseInt and validate with Number.isFinite before passing
  3. If you want 'no sampling', omit sampleIntervalMs entirely and use the 5000ms default rather than passing 0
  4. Fix the upstream computation that produced NaN or 0

Example fix

// before
createControlPlaneViewSource({ sampleIntervalMs: process.env.SAMPLE_MS })
// after
const ms = Number(process.env.SAMPLE_MS);
createControlPlaneViewSource({ sampleIntervalMs: Number.isFinite(ms) && ms > 0 ? ms : undefined });
Defensive patterns

Strategy: validation

Validate before calling

function validInterval(ms) { return ms === undefined || (Number.isFinite(ms) && ms > 0); }
// only pass sampleIntervalMs if validInterval(sampleIntervalMs)

Type guard

const isPositiveFinite = (n) => typeof n === 'number' && Number.isFinite(n) && n > 0;

Try / catch

try { createControlPlaneViewSource(deps); } catch (e) {
  if (String(e.message).includes('sampleIntervalMs')) console.error('Fix sampleIntervalMs:', deps.sampleIntervalMs);
  else throw e;
}

Prevention

When it happens

Trigger: Calling createControlPlaneViewSource({ sampleIntervalMs: 0 }) or { sampleIntervalMs: -1 }, or passing a non-finite value (NaN, Infinity) or a string like '5000' instead of a number. Omitting it is fine (defaults to 5000).

Common situations: Reading the interval from an env var or query string without Number conversion (getting a string); a config file exporting 0 meaning 'no delay'; arithmetic producing NaN before construction.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/90a94961f4d9d17b. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/control-pane/control-plane-view.js:325

    limits: [
      'Advisories use static thresholds; no learned threshold and no conflict-reduction claim.',
      'Projection is a display over the shipped channels x_tree, x_overlap, x_dep; it does not change risk.',
      'Inventory rows are declared-only observations; leases are not locks.',
      'The view does not steer, pause or lock any agent.'
    ]
  };
}

/**
 * Stateful view builder for a long-lived server: keeps one projection window
 * so z-scores roll over ticks. `buildSnapshot()` is injected (it is the
 * control-pane snapshot with includeProximity: true).
 */
function createControlPlaneViewSource(deps = {}) {
  const window = deps.window || createProjectionWindow(deps.projection || {});
  const clock = deps.clock || Date.now;
  const interval = deps.sampleIntervalMs === undefined ? 5000 : deps.sampleIntervalMs;
  if (!Number.isFinite(interval) || interval <= 0) throw new Error('sampleIntervalMs must be positive and finite');
  let cached = null;
  let pending = null;
  let expiresAt = 0;
  async function refresh() {
    const snapshot = await deps.buildSnapshot();
    const view = buildControlPlaneView(snapshot, { ...deps.viewOptions, window });
    cached = { snapshot, view };
    expiresAt = clock() + interval;
    return cached;
  }
  return {
    window,
    async build(extra = {}) {
      if (!cached || clock() >= expiresAt) {
        if (!pending) pending = refresh().finally(() => { pending = null; });
        await pending;
      }
      if (Object.keys(extra).length === 0) return cached.view;

View on GitHub (pinned to 8321021c54)