PHPOffice/PhpSpreadsheet · error · SpreadsheetException

Value could not be bound to cell.

Error message

Value could not be bound to cell.

What it means

When a Cell is constructed with setValue()/getCell() and no explicit data type, PhpSpreadsheet runs the configured IValueBinder (default DefaultValueBinder, optionally AdvancedValueBinder or a custom one). If bindValue() returns false, the constructor throws PhpOffice\PhpSpreadsheet\Exception 'Value could not be bound to cell.' - the binder rejected the value. Binders return false for content they cannot classify (e.g. AdvancedValueBinder with unparseable formula-looking strings in some versions, or custom binders enforcing domain rules).

Source

Thrown at src/PhpSpreadsheet/Cell/Cell.php:119

     */
    public function __construct(mixed $value, ?string $dataType, Worksheet $worksheet)
    {
        // Initialise cell value
        $this->value = $value;

        // Set worksheet cache
        $this->parent = $worksheet->getCellCollection();

        // Set datatype?
        if ($dataType !== null) {
            if ($dataType == DataType::TYPE_STRING2) {
                $dataType = DataType::TYPE_STRING;
            }
            $this->dataType = $dataType;
        } else {
            $valueBinder = $worksheet->getParent()?->getValueBinder() ?? self::getValueBinder();
            if ($valueBinder->bindValue($this, $value) === false) {
                throw new SpreadsheetException('Value could not be bound to cell.');
            }
        }
        $this->ignoredErrors = new IgnoredErrors();
    }

    /**
     * Get cell coordinate column.
     *
     * @throws SpreadsheetException
     */
    public function getColumn(): string
    {
        $parent = $this->parent;
        if ($parent === null) {
            throw new SpreadsheetException('Cannot get column when cell is not bound to a worksheet');
        }

        return $parent->getCurrentColumn();

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Inspect your binder: make it throw a meaningful exception (or coerce) instead of returning false, or fix the data it rejects
  2. Set the value with an explicit type to bypass binding: $cell->setValueExplicit($value, DataType::TYPE_STRING)
  3. Pre-validate/sanitize the value in PHP so the binder accepts it
  4. Ensure your IValueBinder implementation never returns false for values you actually need to store

Example fix

// before: binder rejects -> constructor throws
$sheet->getCell('A1')->setValue($userInput);

// after: store explicitly without binder interpretation
use PhpOffice\PhpSpreadsheet\Cell\DataType;
$sheet->getCell('A1')->setValueExplicit((string) $userInput, DataType::TYPE_STRING);
Defensive patterns

Strategy: fallback

Validate before calling

// Know your binder before writing values
$binder = $sheet->getParent()?->getValueBinder() ?? Cell::getValueBinder();
if ($binder instanceof MyStrictBinder && !MyStrictBinder::accepts($value)) {
    $sheet->getCell('A1')->setValueExplicit((string) $value, DataType::TYPE_STRING);
    return;
}
$sheet->getCell('A1')->setValue($value);

Type guard

function binderAccepts(\PhpOffice\PhpSpreadsheet\Cell\IValueBinder $b, mixed $value, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $ws): bool
{
    $probe = $ws->getCell((string) max(1, $ws->getHighestRow() + 1) . 'Z' /* scratch cell */);
    try {
        $probe->setValue($value);
        return true;
    } catch (\PhpOffice\PhpSpreadsheet\Exception) {
        return false;
    }
}

Try / catch

try {
    $sheet->getCell('A1')->setValue($value);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
    if (str_contains($e->getMessage(), 'could not be bound')) {
        $sheet->getCell('A1')->setValueExplicit((string) $value, DataType::TYPE_STRING);
    } else { throw $e; }
}

Prevention

When it happens

Trigger: $sheet->getCell('A1')->setValue($value) where the active value binder's bindValue() returns false; Cell::setValueAndOverrideBinder()/setValueExplicit with a custom binder that rejects the value; IValueBinder implementations that return false instead of throwing for invalid input; Cells created directly with new Cell($value, 'A1', $sheet) under such a binder.

Common situations: Custom corporate value binders validating types/formats (rejecting e.g. malformed dates or forbidden strings) that signal rejection by returning false; switching DefaultValueBinder -> AdvancedValueBinder and hitting newly-rejected inputs; binder code updated to stricter rules without updating the data feeding it.

Related errors


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