symfony/polyfill-mbstring · error · ValueError

Argument #2 ($length) must be greater than 0

Error message

Argument #2 ($length) must be greater than 0

What it means

Mbstring::mb_str_split() throws this ValueError when the $length argument is not greater than 0. Splitting a string into zero-length or negative-length segments is meaningless, so the polyfill rejects it; on PHP < 8.0 it triggers an E_USER_WARNING and returns false instead.

Solutions

  1. Pass a positive integer for $length (>= 1)
  2. Clamp or validate the computed length before calling: max(1, $n)
  3. Cast carefully and reject non-numeric/zero user input before splitting
  4. Catch \ValueError (PHP 8+) or check for false + warning (PHP < 8)

Example fix

// before
mb_str_split($s, $chunkSize); // $chunkSize could be 0
// after
mb_str_split($s, max(1, (int) $chunkSize));
Defensive patterns

Strategy: validation

Validate before calling

$length = (int) $length;
if ($length < 1) {
    throw new \InvalidArgumentException('length must be >= 1');
}
mb_str_split($string, $length);

Type guard

function isPositiveInt($length): bool
{
    return is_int($length) && $length > 0;
}

Try / catch

try {
    $chunks = mb_str_split($string, $length);
} catch (\ValueError $e) {
    $chunks = mb_str_split($string, 1);
}

Prevention

When it happens

Trigger: Calling mb_str_split($string, 0), mb_str_split($string, -1), or any $length <= 0 — typically from a computed/unvalidated length value.

Common situations: A config or CLI value of 0 or a negative number used as chunk size; an off-by-one or wrong-variable bug when computing segment length; user input parsed with (int) cast producing 0 for non-numeric input.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of symfony/polyfill-mbstring@d3d318bad5 (2026-09-13). Data as JSON: /api/errors/efc7e3ea796fec7e. Report an issue: GitHub.

Appendix: source

Thrown at Mbstring.php:626

        return false !== $pos ? $offset + $pos : false;
    }

    public static function mb_str_split($string, $split_length = 1, $encoding = null)
    {
        if (null !== $string && !\is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) {
            trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING);

            return null;
        }

        if (1 > $split_length = (int) $split_length) {
            if (80000 > \PHP_VERSION_ID) {
                trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);

                return false;
            }

            throw new \ValueError('Argument #2 ($length) must be greater than 0');
        }

        if (null === $encoding) {
            $encoding = mb_internal_encoding();
        }

        if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
            $rx = '/(';
            while (65535 < $split_length) {
                $rx .= '.{65535}';
                $split_length -= 65535;
            }
            $rx .= '.{'.$split_length.'})/us';

            return preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
        }

        $result = [];

View on GitHub (pinned to d3d318bad5)