{"record":{"id":"cfc3519816151383","repo":"PHPOffice/PhpSpreadsheet","slug":"scale-must-not-be-negative","errorCode":null,"errorMessage":"Scale must not be negative","messagePattern":"Scale must not be negative","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/PageSetup.php","lineNumber":353,"sourceCode":"     * Set Scale.\n     * Print scaling. Valid values range from 10 to 400\n     * This setting is overridden when fitToWidth and/or fitToHeight are in use.\n     *\n     * @param bool $update Update fitToPage so scaling applies rather than fitToHeight / fitToWidth\n     *\n     * @return $this\n     */\n    public function setScale(?int $scale, bool $update = true): static\n    {\n        // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,\n        // but it is apparently still able to handle any scale >= 0, where 0 results in 100\n        if ($scale === null || $scale >= 0) {\n            $this->scale = $scale;\n            if ($update) {\n                $this->fitToPage = false;\n            }\n        } else {\n            throw new PhpSpreadsheetException('Scale must not be negative');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get Fit To Page.\n     */\n    public function getFitToPage(): bool\n    {\n        return $this->fitToPage;\n    }\n\n    /**\n     * Set Fit To Page.\n     *\n     * @return $this\n     */","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/PageSetup.php#L335-L371","documentation":"PageSetup::setScale() stores the print zoom percentage for a worksheet. Excel's UI only permits 10-400, but the file format tolerates any non-negative integer (0 is written and Excel reads it as 100) and null resets to 100; the only rejected input is a negative integer, which throws 'Scale must not be negative'. Note that a successful setScale($scale, true) also disables fitToPage.","triggerScenarios":"$sheet->getPageSetup()->setScale(-15); a computed percentage going negative (e.g. 100 - $reduction * 100 style math); unvalidated user input like '-50' cast to int.","commonSituations":"Zoom derived arithmetically from data or request parameters; sanitized-too-late form input; porting code from libraries that clamped silently.","solutions":["Clamp before setting: setScale(max(0, $scale)).","If the goal is automatic sizing, use setFitToPage/setFitToWidth/setFitToHeight instead of computing a scale.","Validate and cast numeric input before it reaches page setup."],"exampleFix":"// before\n$sheet->getPageSetup()->setScale($zoom); // $zoom = -20 -> throws\n\n// after\n$sheet->getPageSetup()->setScale(max(0, (int) $zoom));","handlingStrategy":"validation","validationCode":"$scale = max(0, (int) $zoom);\n$sheet->getPageSetup()->setScale($scale);","typeGuard":"function isValidPrintScale(?int $scale): bool\n{\n    return $scale === null || $scale >= 0;\n}","tryCatchPattern":"try {\n    $sheet->getPageSetup()->setScale($scale);\n} catch (PhpSpreadsheetException $e) {\n    $sheet->getPageSetup()->setScale(100);\n}","preventionTips":["Clamp scale with max(0, ...) at the input boundary","For automatic page fitting use setFitToWidth/setFitToHeight instead of computed percentages","Remember scale 0 is legal and written as-is; Excel reads it as 100"],"tags":["php","phpspreadsheet","page-setup","print-scale","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}