PHPOffice/PhpSpreadsheet · error · Exception

#VALUE!

#VALUE!

Error message

#VALUE!

What it means

#VALUE! from the bitwise argument validator when the value is not numeric at all (after null/bool have been coerced to numbers). validateBitwiseArgument() falls through to throw Calculation\Exception('#VALUE!') for strings like 'abc', objects, resources, etc.; BITAND/BITOR/BITXOR/BITLSHIFT/BITRSHIFT return it as the '#VALUE!' result string.

Source

Thrown at src/PhpSpreadsheet/Calculation/Engineering/BitWise.php:213

     */
    private static function validateBitwiseArgument(mixed $value): float
    {
        $value = self::nullFalseTrueToNumber($value);

        if (is_numeric($value)) {
            $value = (float) $value;
            if ($value == floor($value)) {
                if (($value > 2 ** 48 - 1) || ($value < 0)) {
                    throw new Exception(ExcelError::NAN());
                }

                return floor($value);
            }

            throw new Exception(ExcelError::NAN());
        }

        throw new Exception(ExcelError::VALUE());
    }

    /**
     * Validate arguments passed to the bitwise functions.
     */
    private static function validateShiftAmount(mixed $value): int
    {
        $value = self::nullFalseTrueToNumber($value);

        if (is_numeric($value)) {
            if (abs($value + 0) > 53) {
                throw new Exception(ExcelError::NAN());
            }

            return (int) $value;
        }

        throw new Exception(ExcelError::VALUE());

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Coerce or verify operands are numeric before calling (is_numeric() on the scalar, or Cell::getValue() + datatype check when reading cells).
  2. Reject or clean non-numeric input at the API boundary instead of relying on the formula to fail.
  3. Check returned values for '#VALUE!' when operands come from users.

Example fix

// before
$result = BitWise::BITAND($cellValue, 0xFF); // $cellValue = 'N/A' -> '#VALUE!'

// after
$result = is_numeric($cellValue)
    ? BitWise::BITAND((int) $cellValue, 0xFF)
    : 0; // or throw your own domain exception
Defensive patterns

Strategy: type-guard

Validate before calling

if (!is_numeric($operand)) {
    throw new \InvalidArgumentException('bitwise operand must be numeric, got ' . gettype($operand));
}
$result = BitWise::BITAND((int) $operand, 0xFF);

Type guard

/** Bitwise operands must be numeric (null/bool are coerced to 0/1 by the engine). */
function isCoercibleBitwiseValue(mixed $v): bool
{
    return $v === null || is_bool($v) || is_numeric($v);
}

Prevention

When it happens

Trigger: =BITAND("x", 1); BitWise::BITOR('hello', 2); a cell containing text used as a bitwise operand; null and true/false are accepted (0/1) but any other non-numeric type or string fails.

Common situations: Referencing text cells or headers in bitwise formulas; unvalidated string input from forms/APIs; Excel files where a column has mixed types.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/9be5a6b3fba77086. Report an issue: GitHub.