Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

chkltlabs's avatar

Attribute must return a relationship instance?

I have an eloquent model with the new accessor syntax.

//my model has this attribute
    public function name_of_thing(): Attribute
    {
        return Attribute::make(
            get: fn () => 'string I want to return',
        );
    }

calling it as an attribute throws this error:

$d->name_of_thing

   LogicException  App\Models\MyModel::name_of_thing must return a relationship instance.

But calling it as a method returns the Attribute instance:

$d->name_of_thing()

= Illuminate\Database\Eloquent\Casts\Attribute {#5678
    +get: Closure() {#5677 …4},
    +set: null,
    +withCaching: false,
    +withObjectCaching: true,
  }

What am I missing here?

0 likes
4 replies
chkltlabs's avatar

In troubleshooting, changing the method name from name_of_thing() to nameOfThing() seems to have fixed it. Still, is this an intended behavior? So odd.

tykus's avatar
tykus
Best Answer
Level 104

@chkltlabs that is the intended behaviour; see the firstName example in the docs

In addition, if you source-dive the HasAttributes trait; you will see that it looks for a callable with the camel-case version of the key; so name_of_thing in camel case is nameOfThing

2 likes
Karthik_hebbar's avatar

I ran into a similar issue, below is the function

public function formattedLocation()
    {
        return Attribute::make(
            get: (fn () => $this->location->name."," . $this->location->city->name)
        );
    }

when i did $theatre->formatted_location, i got "App\Models\Theater::formattedLocation must return a relationship instance."

adding the typehint of the returning type solved it for me.

public function formattedLocation() :Attribute
    {
        return Attribute::make(
            get: (fn () => $this->location->name."," . $this->location->city->name)
        );
    }

still not sure why it worked, putting it out here if anyone facing this weird problem and for someone to shed light on why it worked...

2 likes

Please or to participate in this conversation.