Risk Level
MEDIUM
File
core/src/exchanges/polymarket/normalizer.ts
Findings
- Line 80:
const candle = buckets.get(snappedMs)!; — placed in the else branch of if (!buckets.has(snappedMs)) { buckets.set(...); } else { ... }. Logically safe because the else guarantees buckets.has(snappedMs) is true. TypeScript does not track the has/get relationship, hence the !.
What Happens When It's Wrong
In practice this should never crash given the surrounding control flow. The risk is a future refactor that restructures the if/else without removing the !, allowing candle to be undefined while lines 81–84 attempt property assignments on it.
Suggested Fix
Use a local variable narrowing to remove the assertion entirely:
const candle = buckets.get(snappedMs);
if (candle) {
candle.high = Math.max(candle.high, price);
candle.low = Math.min(candle.low, price);
candle.close = price;
candle.volume = (candle.volume || 0) + volume;
}
Found by automated non-null assertion audit
Risk Level
MEDIUM
File
core/src/exchanges/polymarket/normalizer.tsFindings
const candle = buckets.get(snappedMs)!;— placed in theelsebranch ofif (!buckets.has(snappedMs)) { buckets.set(...); } else { ... }. Logically safe because theelseguaranteesbuckets.has(snappedMs)is true. TypeScript does not track thehas/getrelationship, hence the!.What Happens When It's Wrong
In practice this should never crash given the surrounding control flow. The risk is a future refactor that restructures the if/else without removing the
!, allowingcandleto beundefinedwhile lines 81–84 attempt property assignments on it.Suggested Fix
Use a local variable narrowing to remove the assertion entirely:
Found by automated non-null assertion audit