{"record":{"id":"a387276b8fa6a611","repo":"PHPOffice/PhpSpreadsheet","slug":"num-a38727","errorCode":"#NUM!","errorMessage":"#NUM!","messagePattern":"#NUM!","errorType":"error_code","errorClass":"PhpOffice\\PhpSpreadsheet\\Calculation\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Calculation/Engineering/ConvertHex.php","lineNumber":170,"sourceCode":"        }\n\n        try {\n            $value = self::validateValue($value);\n            $value = self::validateHex($value);\n            $places = self::validatePlaces($places);\n        } catch (Exception $e) {\n            return $e->getMessage();\n        }\n\n        $decimal = self::toDecimal($value);\n\n        return ConvertDecimal::toOctal($decimal, $places);\n    }\n\n    protected static function validateHex(string $value): string\n    {\n        if (strlen($value) > preg_match_all('/[0123456789ABCDEF]/', $value)) {\n            throw new Exception(ExcelError::NAN());\n        }\n\n        return $value;\n    }\n}\n","sourceCodeStart":152,"sourceCodeEnd":176,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Calculation/Engineering/ConvertHex.php#L152-L176","documentation":"#NUM! from the hexadecimal validator used by HEX2BIN, HEX2DEC and HEX2OCT. ConvertHex::validateHex() runs on the uppercased value and throws Calculation\\Exception('#NUM!') when it contains any character outside [0-9A-F], matching Excel's behaviour for invalid hex numbers.","triggerScenarios":"=HEX2DEC(\"G1\"), =HEX2DEC(\"0x1F\") ('X' is invalid after uppercasing), =HEX2BIN(\"1F \") (trailing space); PHP calls ConvertHex::toDecimal('XYZ') or values with # color prefixes like '#FF' ('#' fails).","commonSituations":"Hex strings carrying '0x' or '#' prefixes from programming/design contexts; mixed-case is fine (value is uppercased first) but any separator, sign or whitespace is not; values pasted from colour pickers or GUID fragments.","solutions":["Strip prefixes and non-hex characters first: $hex = preg_replace('/^0x|^#/i', '', trim($v)).","Validate with preg_match('/^[0-9A-F]+$/i', $v)) before calling HEX2* functions.","Convert oversized hex in PHP with hexdec()/gmp instead of the Excel wrappers."],"exampleFix":"// before\n$dec = ConvertHex::toDecimal('0x1F'); // '#NUM!'\n\n// after\n$hex = strtoupper(preg_replace('/^(0x|#)/i', '', trim('0x1F'))); // '1F'\n$dec = ConvertHex::toDecimal($hex);","handlingStrategy":"validation","validationCode":"$hex = strtoupper(preg_replace('/^(0x|#)/i', '', trim((string) $value)));\nif (!preg_match('/^[0-9A-F]{1,}$/', $hex)) {\n    throw new \\InvalidArgumentException('value contains non-hex characters');\n}\n$dec = ConvertHex::toDecimal($hex);","typeGuard":"/** HEX2* input: hex digits only after stripping 0x/# prefixes. */\nfunction isValidHexString(mixed $v): bool\n{\n    return is_string($v) && preg_match('/^[0-9A-Fa-f]+$/', $v) === 1;\n}","tryCatchPattern":null,"preventionTips":["Strip '0x' and '#' prefixes (colour codes!) before conversion.","Case does not matter (input is uppercased) but separators, spaces and signs do.","For >10-digit hex use hexdec()/GMP rather than the Excel wrappers."],"tags":["phpspreadsheet","excel-formula","base-conversion","hexadecimal","pattern-validation"],"backgroundTag":"excel-num-error","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}