plotly/plotly.js · info
encountered bad format: "${key}"
Error message
encountered bad format: "${key}" What it means
lib.warnBadFormat warns 'encountered bad format: "<f>"' the first time a formatting function/string that isn't a recognized d3-format specifier is used in tick/tickformat or hover template value formatting; repeats are suppressed via seenBadFormats. After warning, the value falls back to a plain String conversion (noFormat).
Source
Thrown at src/lib/index.js:41
// that prefix before deciding whether to trim, and reattach it: prepending
// the tilde to the whole string (e.g. "~+.2f") is an invalid spec that
// d3Format rejects, so "+.2f" used to be silently dropped.
var prefix = (formatStr.match(/^[+\-( ]?/) || [''])[0];
var rest = formatStr.slice(prefix.length);
// try adding tilde to trim trailing zeros; leave symbol-led specs ($, #)
// untrimmed, since the symbol isn't part of the prefix we stripped above
if (!/^[~,.0$#]/.test(rest) && /[&fps]/.test(rest)) return prefix + '~' + rest;
return formatStr;
};
var seenBadFormats = {};
lib.warnBadFormat = function (f) {
var key = String(f);
if (!seenBadFormats[key]) {
seenBadFormats[key] = 1;
lib.warn('encountered bad format: "' + key + '"');
}
};
lib.noFormat = function (value) {
return String(value);
};
lib.numberFormat = function (formatStr) {
var fn;
try {
fn = d3Format(lib.adjustFormat(formatStr));
} catch (e) {
lib.warnBadFormat(formatStr);
return lib.noFormat;
}
return fn;
};View on GitHub (pinned to 1d090e0b5f)
Solutions
- Replace the format string with valid d3-format syntax for numbers (e.g. ',.2f', '.0%', '$,.0f').
- For dates, use d3 time-format syntax via layout's tickformat with codes like '%Y-%m-%d' only inside valid specifier context, or set tickformatstops with proper d3.time.format values where applicable.
- Check that the value at the warning site is what you intended — the suppressed repeat means you'll only see the first occurrence.
- Strip strftime-style '%' date patterns or convert them explicitly before assignment.
- Test formatting on a minimal figure to isolate which attribute carries the bad format.
Example fix
// before
layout: {yaxis: {tickformat: '0.00x'}} // invalid d3 format
// after
layout: {yaxis: {tickformat: '.2%'}} Defensive patterns
Strategy: validation
Validate before calling
function isValidD3Format(f) {
try {
require('d3-format').format(f);
return true;
} catch (e) {
return false;
}
}
axis.tickformat = isValidD3Format(requested) ? requested : ',.2f'; Type guard
function isFormatSpecifier(v) {
return typeof v === 'string' && /^[-+ #(0]*[0-9]*(\.[0-9]+)?[~s%eEfgGnpqoxXbBcdjZ]+$/.test(v.trim());
} Try / catch
if (!isFormatSpecifier(cfg.tickformat)) {
console.warn('replacing bad tickformat', cfg.tickformat);
cfg.tickformat = ',.2f';
} Prevention
- Use d3-format syntax for numbers (',.2f', '.0%'), not strftime patterns.
- Convert matplotlib/strftime habits explicitly before assigning tickformat.
- Keep a minimal test figure exercising tickformat from user config.
- Remember the warning prints only once per format — search data flows, not logs, for repeats.
When it happens
Trigger: Setting tickformat, hoverformat, or a text/template formatting value to something d3-format rejects — e.g. tickformat: '%s' (strftime-style instead of d3), '0.00x', an empty string used where a format was expected, or passing a custom object as a formatter.
Common situations: Migrating from matplotlib/strftime habits ('%Y-%m-%d') into d3-format syntax ('%Y-%m-%d' is invalid; d3 uses ~%Y-%m-%d or the d3 time format object); typos like '0.0%' misspelled; generating tickformat strings from user config.
AI-assisted analysis of plotly/plotly.js@1d090e0b5f (2026-09-02).
Data as JSON: /api/errors/e2e191cfc7b965f3.
Report an issue: GitHub.