trekhleb/javascript-algorithms · error · Error
Items and weights must be of the same size
Error message
Items and weights must be of the same size
What it means
weightedRandom(items, weights) requires exactly one weight per item; the first guard rejects any length mismatch. Weights are accumulated into cumulative sums and a random number in [0, sum] selects the item, so a missing or extra weight leaves the item-to-probability mapping undefined. The size check runs before the emptiness check, so mismatched non-empty arrays always produce this message rather than 'Items must not be empty'.
Source
Thrown at src/algorithms/statistics/weighted-random/weightedRandom.js:18
/**
* Picks the random item based on its weight.
* The items with higher weight will be picked more often (with a higher probability).
*
* For example:
* - items = ['banana', 'orange', 'apple']
* - weights = [0, 0.2, 0.8]
* - weightedRandom(items, weights) in 80% of cases will return 'apple', in 20% of cases will return
* 'orange' and it will never return 'banana' (because probability of picking the banana is 0%)
*
* @param {any[]} items
* @param {number[]} weights
* @returns {{item: any, index: number}}
*/
/* eslint-disable consistent-return */
export default function weightedRandom(items, weights) {
if (items.length !== weights.length) {
throw new Error('Items and weights must be of the same size');
}
if (!items.length) {
throw new Error('Items must not be empty');
}
// Preparing the cumulative weights array.
// For example:
// - weights = [1, 4, 3]
// - cumulativeWeights = [1, 5, 8]
const cumulativeWeights = [];
for (let i = 0; i < weights.length; i += 1) {
cumulativeWeights[i] = weights[i] + (cumulativeWeights[i - 1] || 0);
}
// Getting the random number in a range of [0...sum(weights)]
// For example:
// - weights = [1, 4, 3]View on GitHub (pinned to 85293e3e2b)
Solutions
- Log items.length and weights.length to find the drift
- Rebuild both arrays from one source so they cannot diverge, e.g. derive weights with items.map(...)
- When filtering items, filter index-aligned pairs and unzip afterwards
- For uniform weights pass items.map(() => 1) instead of a hand-maintained array
Example fix
// before import weightedRandom from './src/algorithms/statistics/weighted-random/weightedRandom'; const pick = weightedRandom(['a', 'b', 'c'], [1, 2]); // throws: 3 items vs 2 weights // after const items = ['a', 'b', 'c']; const weights = items.map((item) => (item === 'a' ? 1 : 2)); const pick = weightedRandom(items, weights); // lengths always match
Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(items) || !Array.isArray(weights) || items.length !== weights.length) {
throw new TypeError('items and weights must be arrays of equal length');
}
weightedRandom(items, weights); Type guard
const isWeightedPair = (items, weights) => Array.isArray(items) && Array.isArray(weights) && items.length === weights.length && items.length > 0;
Try / catch
try {
pick = weightedRandom(items, weights);
} catch (e) {
if (e.message === 'Items and weights must be of the same size') {
pick = { item: items[0], index: 0 }; // degrade to first item
} else {
throw e;
}
} Prevention
- Zip items and weights into one structure instead of parallel arrays
- When filtering, filter (item, index) pairs so alignment survives
- Assert equal lengths in a unit test on the config loader
When it happens
Trigger: weightedRandom(['a','b','c'], [1, 2]) (3 items, 2 weights); items extended without extending weights; weights built from a different data source or filtered separately from items.
Common situations: Weights read from config while items come from a database, items filtered (e.g. out-of-stock removed) without refiltering weights, or parallel arrays drifting apart across refactors.
Related errors
- Items must not be empty
- The method supports only positive integers
- The data is empty
- Either dataSet or labels or toClassify were not set
- Strings must be of the same length
AI-assisted analysis of trekhleb/javascript-algorithms@85293e3e2b (2026-08-24).
Data as JSON: /api/errors/b5388bdaad5dbed8.
Report an issue: GitHub.