plotly/plotly.js · warning

randstr failed uniqueness

Error message

randstr failed uniqueness

What it means

plotly.js's randstr() generates pseudo-random string IDs by converting a random number to a given base. When a collision is detected (the string already exists in the `existing` map) or the value exceeds the requested bit range, it recurses to regenerate. If recursion exceeds 10 attempts, it gives up and logs 'randstr failed uniqueness', returning the duplicate/overflowing string anyway.

Source

Thrown at src/lib/index.js:361

    }

    var rem = digits - Math.floor(digits);

    for (i = 0; i < Math.floor(digits); i++) {
        x = Math.floor(Math.random() * base).toString(base);
        res = x + res;
    }

    if (rem) {
        b = Math.pow(base, rem);
        x = Math.floor(Math.random() * b).toString(base);
        res = x + res;
    }

    var parsed = parseInt(res, base);
    if ((existing && existing[res]) || (parsed !== Infinity && parsed >= Math.pow(2, bits))) {
        if (_recursion > 10) {
            lib.warn('randstr failed uniqueness');
            return res;
        }
        return randstr(existing, bits, base, (_recursion || 0) + 1);
    } else return res;
};

lib.OptionControl = function (opt, optname) {
    /*
     * An environment to contain all option setters and
     * getters that collectively modify opts.
     *
     * You can call up opts from any function in new object
     * as this.optname || this.opt
     *
     * See FitOpts for example of usage
     */
    if (!opt) opt = {};
    if (!optname) optname = 'opt';

View on GitHub (pinned to 1d090e0b5f)

Solutions

  1. Increase the `bits` argument to enlarge the key space (e.g. 64 instead of 24).
  2. Reduce the number of pre-existing keys passed in the `existing` map.
  3. Check the returned string for duplicates yourself after the warning and regenerate if needed.
  4. Report upstream if it happens with default arguments on a small graph, as it indicates insufficient randomness.

Example fix

// before
var id = randstr(existing, 12, 16); // only 4096 possible keys
// after
var id = randstr(existing, 64, 16); // much larger key space
Defensive patterns

Strategy: validation

Validate before calling

function checkIdSpace(existingCount, bits) {
  const space = Math.pow(2, bits);
  if (existingCount > space * 0.5) {
    throw new Error('randstr key space too small; increase bits');
  }
}

Type guard

function isUnique(res, existing) { return typeof res === 'string' && !existing[res]; }

Prevention

When it happens

Trigger: Calling randstr(existing, bits, base) where the key space (2^bits at the given base) is too small relative to the number of existing keys, causing >10 consecutive collisions or overflow of the 2^bits limit.

Common situations: Generating many IDs with too few bits (e.g. bits too small for thousands of traces), seeding randstr with an `existing` map that already contains most of the small key space, or Math.random returning clustered values in constrained environments.


AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02). Data as JSON: /api/errors/3bf654d38755d71c. Report an issue: GitHub.