jackwener/OpenCLI · error
Invalid trace maxCountPerProfile: ${maxCountPerProfile}
Error message
Invalid trace maxCountPerProfile: ${maxCountPerProfile} What it means
resolveTraceRetentionPolicy() requires maxCountPerProfile to be a non-negative integer because it caps how many traces are kept per profile. This Error is thrown when the value is fractional (e.g. 10.5), negative, or otherwise not an integer. Complements the maxAgeDays check with the same fail-fast policy.
Source
Thrown at src/observation/retention.ts:63
export function parseByteSize(value: string | number): number {
if (typeof value === 'number') {
if (!Number.isFinite(value) || value < 0) throw new Error(`Invalid byte size: ${value}`);
return Math.floor(value);
}
const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB)?$/i);
if (!match) throw new Error(`Invalid byte size: ${value}`);
const amount = Number(match[1]);
const unit = (match[2] ?? 'B').toUpperCase();
return Math.floor(amount * BYTES_UNITS[unit]);
}
export function resolveTraceRetentionPolicy(input: TraceRetentionPolicyInput = {}): ResolvedTraceRetentionPolicy {
const maxAgeDays = input.maxAgeDays ?? DEFAULT_TRACE_RETENTION_POLICY.maxAgeDays;
const maxCountPerProfile = input.maxCountPerProfile ?? DEFAULT_TRACE_RETENTION_POLICY.maxCountPerProfile;
if (!Number.isFinite(maxAgeDays) || maxAgeDays < 0) throw new Error(`Invalid trace maxAgeDays: ${maxAgeDays}`);
if (!Number.isInteger(maxCountPerProfile) || maxCountPerProfile < 0) {
throw new Error(`Invalid trace maxCountPerProfile: ${maxCountPerProfile}`);
}
return {
maxAgeDays,
maxAgeMs: maxAgeDays * 24 * 60 * 60 * 1000,
maxCountPerProfile,
maxBytesPerProfile: parseByteSize(input.maxBytesPerProfile ?? DEFAULT_TRACE_RETENTION_POLICY.maxBytesPerProfile),
};
}
export function traceExpiresAt(createdAt: string, policyInput: TraceRetentionPolicyInput = {}): string {
const policy = resolveTraceRetentionPolicy(policyInput);
const createdAtMs = Date.parse(createdAt);
const base = Number.isFinite(createdAtMs) ? createdAtMs : Date.now();
return new Date(base + policy.maxAgeMs).toISOString();
}
export function pruneTraceArtifacts(
tracesDir: string,View on GitHub (pinned to 49907e53dc)
Solutions
- Round the value: Math.floor/Math.round to a non-negative integer before passing it.
- Fix the upstream calculation or config so the count is a whole non-negative number.
- Omit maxCountPerProfile to fall back to DEFAULT_TRACE_RETENTION_POLICY.maxCountPerProfile.
Example fix
// before
resolveTraceRetentionPolicy({ maxCountPerProfile: totalTraces / profileCount }) // may be fractional
// after
resolveTraceRetentionPolicy({ maxCountPerProfile: Math.max(0, Math.floor(totalTraces / profileCount)) }) Defensive patterns
Strategy: validation
Validate before calling
function isValidMaxCountPerProfile(v) {
return typeof v === 'number' && Number.isInteger(v) && v >= 0;
}
// if (!isValidMaxCountPerProfile(cfg.maxCountPerProfile)) cfg.maxCountPerProfile = undefined; // use default Type guard
function isMaxCountPerProfile(v: unknown): v is number {
return typeof v === 'number' && Number.isInteger(v) && v >= 0;
} Try / catch
try {
return resolveTraceRetentionPolicy(input);
} catch (e) {
if (e instanceof Error && e.message.includes('maxCountPerProfile')) {
logger.warn(`Bad maxCountPerProfile ${String(input?.maxCountPerProfile)}, falling back to defaults`);
return resolveTraceRetentionPolicy({ ...input, maxCountPerProfile: undefined });
}
throw e;
} Prevention
- Math.floor/round any computed counts before passing them in.
- Schema-validate with z.number().int().nonnegative() at config load.
- Never pass user-supplied strings or percentages; parse and validate to an integer first.
When it happens
Trigger: Calling resolveTraceRetentionPolicy({ maxCountPerProfile: -5 }) or { maxCountPerProfile: 100.5 }; also NaN/Infinity which fail Number.isInteger.
Common situations: Config values divided or averaged at runtime (e.g. total/profiles producing fractions), a negative from a bad formula, or a percent-like value ('50%') parsed loosely in JS.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Invalid trace maxAgeDays: ${maxAgeDays}
- profile contextId is required
- profile alias is required
- profile is required
- TAP_MISSING_PARAMS
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3bc606eee6d05100.
Report an issue: GitHub.