{"record":{"id":"f4a234f1f8e693a3","repo":"Dogfalo/materialize","slug":"nouislider-limit-margin-and-padding-must-b","errorCode":null,"errorMessage":"noUiSlider: 'limit', 'margin' and 'padding' must be divisible by step.","messagePattern":"noUiSlider: 'limit', 'margin' and 'padding' must be divisible by step\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extras/noUiSlider/nouislider.js","lineNumber":400,"sourceCode":"            handleEntryPoint(ordered[index][1], ordered[index][0], this);\n        }\n\n        // Store the actual step values.\n        // xSteps is sorted in the same order as xPct and xVal.\n        this.xNumSteps = this.xSteps.slice(0);\n\n        // Convert all numeric steps to the percentage of the subrange they represent.\n        for ( index = 0; index < this.xNumSteps.length; index++ ) {\n            handleStepPoint(index, this.xNumSteps[index], this);\n        }\n    }\n\n    Spectrum.prototype.getMargin = function ( value ) {\n\n        var step = this.xNumSteps[0];\n\n        if ( step && ((value / step) % 1) !== 0 ) {\n            throw new Error(\"noUiSlider: 'limit', 'margin' and 'padding' must be divisible by step.\");\n        }\n\n        return this.xPct.length === 2 ? fromPercentage(this.xVal, value) : false;\n    };\n\n    Spectrum.prototype.toStepping = function ( value ) {\n\n        value = toStepping( this.xVal, this.xPct, value );\n\n        return value;\n    };\n\n    Spectrum.prototype.fromStepping = function ( value ) {\n\n        return fromStepping( this.xVal, this.xPct, value );\n    };\n\n    Spectrum.prototype.getStep = function ( value ) {","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/Dogfalo/materialize/blob/824e78248b3de81e383445e76ffb04cc3264fe7d/extras/noUiSlider/nouislider.js#L382-L418","documentation":"Thrown by Spectrum.getMargin, which testMargin/testLimit/testPadding all call. If a step is set and value/step has a fractional remainder, the value is not on the step grid and the library refuses it so handle positions stay reachable. The check is (value / step) % 1 !== 0, which is also vulnerable to IEEE-754 rounding for decimal steps.","triggerScenarios":"step: 10, margin: 25 (25/10 = 2.5). step: 5, limit: 12. The classic float trap: step: 0.3, margin: 0.9, because 0.9/0.3 evaluates to 2.9999999999999996 in JS and % 1 is non-zero.","commonSituations":"Mixing step with margin/limit/padding expressed in different units, changing step without updating the others, or using decimal steps that hit floating-point error.","solutions":["Make margin/limit/padding an exact integer multiple of step.","For decimal steps, snap to the grid: margin = Math.round(want / step) * step.","Drop the constraint (set to 0 or omit) if exact divisibility is not required."],"exampleFix":"// before\nstep: 0.3, margin: 0.9   // throws: 0.9/0.3 is 2.9999...\n// after\nstep: 0.3, margin: Math.round(0.9 / 0.3) * 0.3","handlingStrategy":"validation","validationCode":"function snapToStep(value, step) { return step ? Math.round(value / step) * step : value; }\nfunction assertDivisible(value, step) {\n  if (step && (value / step) % 1 !== 0) throw new Error(value + ' must be a multiple of step ' + step);\n}\n['margin','limit','padding'].forEach(k => { if (opts[k] != null) assertDivisible(opts[k], opts.step); });","typeGuard":null,"tryCatchPattern":"try { noUiSlider.create(el, opts); }\ncatch (e) {\n  if (/divisible by step/.test(e.message)) { opts.margin = snapToStep(opts.margin, opts.step); /* retry */ }\n  else throw e;\n}","preventionTips":["Treat step as the source of truth and derive margin/limit/padding from it.","For decimal steps, round the ratio to avoid IEEE-754 remainder errors.","Centralize the constraint check in a validateConfig() helper called before create."],"tags":["config","validation","step","margin","limit","padding","floating-point"],"backgroundTag":null,"analyzedSha":"824e78248b3de81e383445e76ffb04cc3264fe7d","analyzedAt":"2026-08-13T04:14:22.506Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}