octobercms/october · error · SystemException

Value cannot be of type array for

Error message

Value cannot be of type array for 

What it means

All comparison operations except OPERATION_ONE_OF work on a single scalar value. The constructor throws when an array value is paired with any other operation, because the SQL builder cannot compare a column to an array.

Source

Thrown at modules/dashboard/classes/ReportDimensionFilter.php:81

        $knownOperations = [
            self::OPERATION_EQUALS,
            self::OPERATION_MORE_OR_EQUALS,
            self::OPERATION_LESS_OR_EQUALS,
            self::OPERATION_MORE,
            self::OPERATION_LESS,
            self::OPERATION_STARTS_WITH,
            self::OPERATION_STRING_INCLUDES,
            self::OPERATION_ONE_OF
        ];

        if (!in_array($operation, $knownOperations)) {
            throw new SystemException('Invalid filter operation. Supported types: ' . implode(', ', $knownOperations));
        }

        if ($operation === self::OPERATION_ONE_OF && !is_array($value)) {
            throw new SystemException('Value must be of type array for ' . self::OPERATION_ONE_OF . ' operation.');
        } elseif ($operation !== self::OPERATION_ONE_OF && is_array($value)) {
            throw new SystemException('Value cannot be of type array for ' . $operation . ' operation.');
        }

        $this->dataAttributeType = $dataAttributeType;
        $this->attributeName = $attributeName;
        $this->operation = $operation;
        $this->value = $value;
    }

    /**
     * Get the data attribute type
     *
     * @return string
     */
    public function getDataAttributeType(): string
    {
        return $this->dataAttributeType;
    }

View on GitHub (pinned to b608633a7e)

Solutions

  1. Submit a scalar for scalar operations — pick one element (e.g. min of the range) or change the operation to OPERATION_ONE_OF
  2. Normalize payload values based on operation: keep arrays only for one_of
  3. Validate value type against the operation before constructing the filter

Example fix

// before
$filter = new ReportDimensionFilter(
    ReportDimensionFilter::ATTR_TYPE_DIMENSION,
    null,
    ReportDimensionFilter::OPERATION_MORE,
    $payload['value'] // ['min' => 100, 'max' => 200]
);

// after
$filter = new ReportDimensionFilter(
    ReportDimensionFilter::ATTR_TYPE_DIMENSION,
    null,
    ReportDimensionFilter::OPERATION_MORE,
    (int) $payload['value']['min']
);
Defensive patterns

Strategy: validation

Validate before calling

if ($operation !== ReportDimensionFilter::OPERATION_ONE_OF && is_array($value)) {
    if (count($value) === 1) {
        $value = reset($value); // single-element array -> scalar
    } else {
        throw new InvalidArgumentException('Multiple values require the one_of operation');
    }
}
$filter = new ReportDimensionFilter($type, $attribute, $operation, $value);

Type guard

function filterValueMatchesOperation(string $operation, mixed $value): bool
{
    return $operation === ReportDimensionFilter::OPERATION_ONE_OF
        ? is_array($value)
        : !is_array($value);
}

Prevention

When it happens

Trigger: new ReportDimensionFilter(ReportDimensionFilter::ATTR_TYPE_DIMENSION, null, ReportDimensionFilter::OPERATION_MORE, [100, 200]); also switching an operation from one_of to '>' while keeping the array value.

Common situations: Front-ends that always submit arrays regardless of the chosen operator; generic filter builders that normalize all values to arrays.

Related errors


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/8fb0c17c6e4a052f. Report an issue: GitHub.