phalcon/cphalcon · error · Phalcon\Mvc\Model\Exceptions\BelongsToRequiresObject

Only objects can be stored as part of belongs-to relations i

Error message

Only objects can be stored as part of belongs-to relations in '{className}' Relation {relationName}

What it means

Thrown by Model::preSaveRelatedRecords() (phalcon/Mvc/Model.zep:5468): a belongs-to relation was assigned a non-object value. BelongsTo relations hold exactly one referenced model instance, and its primary key is copied into the local FK after the related record is saved, so only objects are accepted. The exception class is Phalcon\Mvc\Model\Exceptions\BelongsToRequiresObject; the implicit transaction is rolled back first.

Source

Thrown at phalcon/Mvc/Model.zep:5468

            let relation = <RelationInterface> manager->getRelationByAlias(
                className,
                name
            );

            if typeof relation === "object" {
                /**
                 * Get the relation type
                 */
                let type = relation->getType();

                /**
                 * Only belongsTo are stored before save the master record
                 */
                if type == Relation::BELONGS_TO {
                    if unlikely typeof record !== "object" {
                        connection->rollback(nesting);

                        throw new BelongsToRequiresObject(get_class(this), name);
                    }

                    /**
                     * If dynamic update is enabled, saving the record must not take any action.
                     * Recursion through circular relations is prevented by the visited
                     * collection inside doSave().
                     */
                    if !record->doSave(visited) {
                        /**
                         * Get the validation messages generated by the
                         * referenced model
                         */
                        this->appendMessagesFrom(record);

                        /**
                         * Rollback the implicit transaction
                         */
                        connection->rollback(nesting);

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Assign a model instance: $invoice->customer = Customer::findFirst(123);
  2. If you only have the key, set the FK column directly instead of the relation property
  3. For create-from-scratch flows, build the related model first: $invoice->customer = new Customer([...]);

Example fix

// before
$invoice = new Invoice([...]);
$invoice->customer = 123; // BelongsToRequiresObject
$invoice->save();

// after
$invoice->customer = Customer::findFirst(123);
// or set the FK directly:
$invoice->customerId = 123;
$invoice->save();
Defensive patterns

Strategy: type-guard

Validate before calling

if (isset($invoice->customer) && !$invoice->customer instanceof \Phalcon\Mvc\ModelInterface) {
    // belongsTo relation must hold a model instance before save()
    $invoice->customer = Customer::findFirst((int) $invoice->customer);
}

Type guard

function isModelInstance($value): bool
{
    return $value instanceof \Phalcon\Mvc\ModelInterface;
}

// before save:
if (null !== $invoice->customer && !isModelInstance($invoice->customer)) {
    throw new InvalidArgumentException('customer relation expects a Model instance');
}

Try / catch

try {
    $invoice->save();
} catch (\Phalcon\Mvc\Model\Exceptions\BelongsToRequiresObject $e) {
    // relation property holds a scalar; set the FK column instead
    $relationName = 'customer'; // parse from message tail
    $invoice->{$relationName . 'Id'} = $scalarId;
    $invoice->save();
}

Prevention

When it happens

Trigger: Assigning a scalar to a belongsTo relation property and saving: $invoice->customer = 123; $invoice->save(). Also assigning an array, a stdClass, or null where a Model instance is required.

Common situations: Confusing FK column assignment ($invoice->customerId = 123) with relation assignment ($invoice->customer = 123); API payloads hydrated directly into relation properties; refactoring from raw FK properties to relations without updating setters.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/73f0b319f1d3606b. Report an issue: GitHub.