mongodb/laravel-mongodb · error · BadMethodCallException

Method ::initializeModelAttributes() requires Laravel 13 or…

Error message

Method %s::initializeModelAttributes() requires Laravel 13 or later. It is called by the model constructor and must not be called directly.

What it means

DocumentModel::initializeModelAttributes() hooks into Laravel 13's model-constructor attribute-initialization API. If the parent Eloquent Model lacks that method (Laravel 12 or earlier), the trait throws BadMethodCallException. It is intended to be invoked only by the model constructor internals.

Solutions

  1. Upgrade Laravel to 13 or later when using DocumentModel-based models
  2. Do not call initializeModelAttributes() manually — let the model constructor do it
  3. If on Laravel <=12, use the older BaseModel integration path of laravel-mongodb instead of DocumentModel
  4. Remove explicit calls from custom constructor overrides

Example fix

// before
public function __construct(array $attributes = [])
{
    parent::__construct($attributes);
    $this->initializeModelAttributes();
}
// after
public function __construct(array $attributes = [])
{
    parent::__construct($attributes); // constructor initializes attributes on Laravel 13+
}
Defensive patterns

Strategy: validation

Validate before calling

if (!method_exists(Model::class, 'initializeModelAttributes')) {
    throw new RuntimeException('DocumentModel requires Laravel 13+');
}

Type guard

function supportsDocumentModel(): bool {
    return method_exists(\Illuminate\Database\Eloquent\Model::class, 'initializeModelAttributes');
}

Try / catch

try {
    $model = new MyDocumentModel();
} catch (BadMethodCallException $e) {
    if (str_contains($e->getMessage(), 'requires Laravel 13')) {
        // upgrade Laravel or switch to the legacy base model
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Calling initializeModelAttributes() directly on a Document-derived model; running the package with Laravel 12 or older while using a model based on DocumentModel; manually invoking the method from custom constructor overrides.

Common situations: Upgrading laravel-mongodb ahead of (or behind) the framework version; copying code that touches the method from an older integration guide; overriding the model constructor and calling the method explicitly.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15). Data as JSON: /api/errors/caea6bbe26df1dfb. Report an issue: GitHub.

Appendix: source

Thrown at src/Eloquent/DocumentModel.php:105

        $value ??= $this->attributes['id'] ?? $this->attributes['_id'] ?? null;

        // Convert ObjectID to string.
        if ($value instanceof ObjectID) {
            return (string) $value;
        }

        if ($value instanceof Binary) {
            return (string) $value->getData();
        }

        return $value;
    }

    /** @inheritdoc */
    public function initializeModelAttributes()
    {
        if (! method_exists(parent::class, 'initializeModelAttributes')) {
            throw new BadMethodCallException(sprintf('Method %s::initializeModelAttributes() requires Laravel 13 or later. It is called by the model constructor and must not be called directly.', static::class));
        }

        parent::initializeModelAttributes();

        $keyType = static::resolveClassAttribute(Table::class)?->keyType;

        if ($keyType === null) {
            return;
        }

        $declaringClass = (new ReflectionProperty($this, 'keyType'))->getDeclaringClass()->getName();

        if ($declaringClass !== Model::class && $declaringClass !== MongoDBModel::class) {
            return;
        }

        $this->keyType = $keyType;
    }

View on GitHub (pinned to 0634653039)