affaan-m/ECC · error · Error

Canonical session snapshot requires ${fieldPath} to be a non

Error message

Canonical session snapshot requires ${fieldPath} to be a non-negative integer

What it means

Thrown by the ensureInteger helper when a field must be a non-negative integer but is not. Applied to aggregates.workerCount, and each value in aggregates.states and aggregates.healths. Used to validate the precomputed rollups match the workers array.

Source

Thrown at scripts/lib/session-adapters/canonical-session.js:65

    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a string or null`);
  }
}

function ensureBoolean(value, fieldPath) {
  if (typeof value !== 'boolean') {
    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a boolean`);
  }
}

function ensureArrayOfStrings(value, fieldPath) {
  if (!Array.isArray(value) || value.some(item => typeof item !== 'string')) {
    throw new Error(`Canonical session snapshot requires ${fieldPath} to be an array of strings`);
  }
}

function ensureInteger(value, fieldPath) {
  if (!Number.isInteger(value) || value < 0) {
    throw new Error(`Canonical session snapshot requires ${fieldPath} to be a non-negative integer`);
  }
}

const STALE_THRESHOLD_MS = 5 * 60 * 1000;

function parseUpdatedMs(updated) {
  if (typeof updated !== 'string' || updated.length === 0) return null;
  const ms = Date.parse(updated);
  return Number.isNaN(ms) ? null : ms;
}

function deriveWorkerHealth(rawWorker) {
  const state = (rawWorker.status && rawWorker.status.state) || 'unknown';
  const completedStates = ['completed', 'succeeded', 'success', 'done'];
  const failedStates = ['failed', 'error'];

  if (failedStates.includes(state)) return 'degraded';
  if (completedStates.includes(state)) return 'healthy';

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Build aggregates via buildAggregates(workers) rather than hand-constructing them, so counts are correct integers.
  2. Ensure any custom count is Number.isInteger and >= 0 before assigning.
  3. Re-run buildAggregates after mutating the workers array.

Example fix

// before
aggregates: { workerCount: workers.length.toFixed(0), states: {}, healths: {} } // string

// after
aggregates: buildAggregates(workers) // { workerCount: number, states, healths }
Defensive patterns

Strategy: validation

Validate before calling

// Prefer buildAggregates so counts are valid non-negative integers.
const { buildAggregates } = require('./canonical-session');
aggregates: buildAggregates(workers)

Type guard

function isNonNegInt(v) { return Number.isInteger(v) && v >= 0; }

Prevention

When it happens

Trigger: aggregates.workerCount set to a float, a negative number, a string like '3', or undefined; a state count value that is a string; aggregates built without Number.isInteger checks.

Common situations: An adapter building aggregates manually and leaving workerCount unset; a count coerced to string during serialization elsewhere; negative counts from a buggy reducer; floats from averaging.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/50e376018d9f4264. Report an issue: GitHub.