{"record":{"id":"e2e191cfc7b965f3","repo":"plotly/plotly.js","slug":"encountered-bad-format-key","errorCode":null,"errorMessage":"encountered bad format: \"${key}\"","messagePattern":"encountered bad format: \"(.+?)\"","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/lib/index.js","lineNumber":41,"sourceCode":"    // that prefix before deciding whether to trim, and reattach it: prepending\n    // the tilde to the whole string (e.g. \"~+.2f\") is an invalid spec that\n    // d3Format rejects, so \"+.2f\" used to be silently dropped.\n    var prefix = (formatStr.match(/^[+\\-( ]?/) || [''])[0];\n    var rest = formatStr.slice(prefix.length);\n\n    // try adding tilde to trim trailing zeros; leave symbol-led specs ($, #)\n    // untrimmed, since the symbol isn't part of the prefix we stripped above\n    if (!/^[~,.0$#]/.test(rest) && /[&fps]/.test(rest)) return prefix + '~' + rest;\n\n    return formatStr;\n};\n\nvar seenBadFormats = {};\nlib.warnBadFormat = function (f) {\n    var key = String(f);\n    if (!seenBadFormats[key]) {\n        seenBadFormats[key] = 1;\n        lib.warn('encountered bad format: \"' + key + '\"');\n    }\n};\n\nlib.noFormat = function (value) {\n    return String(value);\n};\n\nlib.numberFormat = function (formatStr) {\n    var fn;\n    try {\n        fn = d3Format(lib.adjustFormat(formatStr));\n    } catch (e) {\n        lib.warnBadFormat(formatStr);\n        return lib.noFormat;\n    }\n\n    return fn;\n};","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/plotly/plotly.js/blob/1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314/src/lib/index.js#L23-L59","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlayout: {yaxis: {tickformat: '0.00x'}} // invalid d3 format\n// after\nlayout: {yaxis: {tickformat: '.2%'}}","handlingStrategy":"validation","validationCode":"function isValidD3Format(f) {\n  try {\n    require('d3-format').format(f);\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\naxis.tickformat = isValidD3Format(requested) ? requested : ',.2f';","typeGuard":"function isFormatSpecifier(v) {\n  return typeof v === 'string' && /^[-+ #(0]*[0-9]*(\\.[0-9]+)?[~s%eEfgGnpqoxXbBcdjZ]+$/.test(v.trim());\n}","tryCatchPattern":"if (!isFormatSpecifier(cfg.tickformat)) {\n  console.warn('replacing bad tickformat', cfg.tickformat);\n  cfg.tickformat = ',.2f';\n}","preventionTips":["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."],"tags":["formatting","d3-format","tickformat"],"backgroundTag":"invalid-format-specifier","analyzedSha":"1d090e0b5ffb8d0fdf6e0e4ff51d3f3cf67f1314","analyzedAt":"2026-09-02T22:03:39.906Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}