Laravel Argument 1 passed to HasOneOrMany::save() must be an instance of Model array given

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company
# Fixing the Eloquent Dilemma: Understanding the `HasOneOrMany::save()` Error Welcome to the world of Laravel! As you dive into building dynamic applications, you will inevitably encounter errors that seem cryptic at first glance. One of the most common stumbling blocks for beginners dealing with Eloquent relationships is figuring out how to correctly save multiple related models. Today, we are going to dissect a very specific error: `Argument 1 passed to HasOneOrMany::save() must be an instance of Model, array given`. This post will walk you through why this error occurs and provide the correct, idiomatic Laravel solution for saving related data in bulk. ## Understanding the Core Problem: Why Eloquent Demands Models The error message is not arbitrary; it is a direct instruction from the Eloquent ORM (Object-Relational Mapper) about how its relationship methods are designed to work. When you define a `hasMany` relationship, such as in your `User` model pointing to `Skill` models, the relationship methods like `save()`, `create()`, or `update()` expect to operate on actual Eloquent Model instances, not raw arrays of data. In your scenario: ```php $user->skills()->saveMany($request->get('skills')); // <-- Error occurs here ``` You are passing an array of attribute arrays (the raw data from the request) to a method that strictly requires an array of `Skill` model objects. The database layer cannot interpret this unstructured array directly as instructions for saving specific records. This principle is fundamental to how Eloquent manages relationships. When you use methods like `saveMany()`, Laravel needs to know *which* models to save, and it achieves this by requiring the input to be fully hydrated Model objects. ## The Solution: Hydrating Data into Models The fix is simple but requires an extra step: transforming the raw array data received from the request into actual Eloquent Models before attempting to save them. This process is often called **hydration**. Instead of passing the raw array, you must iterate over your input data and instantiate new `Skill` models for each entry, filling them with the provided attributes. Here is how you correct your controller logic: ### Step 1: Process the Input Data First, retrieve your raw data, which you correctly identified as an array of arrays: ```php $skillData = $request->get('skills'); // Example: array:5 [...] ``` ### Step 2: Create and Save the Models Next, loop through this data and create a new `Skill` instance for each set of data before calling `saveMany()` on the relationship. ```php public function editMyProfile(Request $request) { $user = Auth::user(); $skillData = $request->get('skills', []); // Ensure we handle empty input gracefully // 1. Create the collection of new Skill models from the raw data $skillsToSave = collect($skillData)->map(function ($data) { return new Skill([ 'skill_title' => $data['skill_title'], 'knowledge_level' => $data['knowledge_level'], ]); })->values(); // .values() ensures the collection is properly indexed // 2. Save the newly created models using saveMany() $user->skills()->saveMany($skillsToSave); return response('Profile updated successfully!'); } ``` ### Best Practice: Using Form Requests for Cleanliness While the above solution fixes the immediate error, a more robust and cleaner approach in larger applications is to use Laravel's **Form Request** validation. This separates the logic of *validation* from the logic of *saving*, making your controller much cleaner. You would define rules on your Form Request to ensure the input structure is correct, and then handle the model creation within a service or directly in the controller, ensuring that you are always working with instantiated models when interacting with Eloquent relationships, as demonstrated by best practices outlined on [laravelcompany.com](https://laravelcompany.com). ## Conclusion The error `Argument 1 passed to HasOneOrMany::save() must be an instance of Model` is a classic example of Eloquent enforcing its object-oriented nature. It forces you to treat your data relationships as actual objects rather than just raw arrays. By mapping your input array into a collection of new Eloquent Models before calling `saveMany()`, you satisfy the requirements of the relationship method, resulting in clean, predictable, and maintainable code. Happy coding!