laravel/framework · error · LogicException

Failed to find resource class for model

Error message

Failed to find resource class for model [%s].

What it means

Thrown by TransformsToResource::guessResource() when toResource() cannot find a JSON resource class for the model. It first checks the UseResource PHP attribute, then guesses two namespace-derived names (e.g. App\Http\Resources\UserResource and App\Http\Resources\User). If neither class exists and there is no attribute, it fails. The guessing only works for models under a \Models\ namespace segment.

Solutions

  1. Pass the resource class explicitly: $model->toResource(UserResource::class).
  2. Add the #[UseResource(UserResource::class)] attribute to the model class.
  3. Create the resource class in the conventional App\Http\Resources namespace (php artisan make:resource UserResource).
  4. Ensure the model lives under a namespace containing \Models\ so the guesser can derive the path.

Example fix

// before (model has no resource and toResource() is called)
return $user->toResource();

// after - option 1: explicit class
return $user->toResource(UserResource::class);

// after - option 2: attribute on the model
use Illuminate\Database\Eloquent\Attributes\UseResource;
#[UseResource(UserResource::class)]
class User extends Model { /* ... */ }
Defensive patterns

Strategy: validation

Validate before calling

// Resolve the resource class up front; fall back to an explicit one
$resourceClass = $model::guessResourceName()[0] ?? null;
if (! is_string($resourceClass) || ! class_exists($resourceClass)) {
    $resourceClass = \App\Http\Resources\FallbackResource::class;
}
return $model->toResource($resourceClass);

Type guard

function hasResolvableResource(string $modelClass): bool {
    if (! class_exists($modelClass)) return false;
    $ref = new \ReflectionClass($modelClass);
    if ($ref->getAttributes(\Illuminate\Database\Eloquent\Attributes\UseResource::class)) return true;
    return collect($modelClass::guessResourceName())
        ->contains(fn ($c) => is_string($c) && class_exists($c));
}

Try / catch

try {
    return $model->toResource();
} catch (\LogicException $e) {
    if (str_contains($e->getMessage(), 'Failed to find resource class')) {
        return \App\Http\Resources\FallbackResource::make($model);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling $model->toResource() on a model that (a) has no #[UseResource(...)] attribute, (b) does not sit in a namespace containing \Models\, or (c) sits in \Models\ but the corresponding App\Http\Resources\<Name>Resource class was never created.

Common situations: Renaming or moving a model without creating the matching resource; using a model outside the conventional Models namespace (e.g. a package model); forgetting to make Artisan resource; calling toResource() in tests without the resource class loaded.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/cc51eaa55f64d510. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Database/Eloquent/Concerns/TransformsToResource.php:49

     * @return \Illuminate\Http\Resources\Json\JsonResource
     *
     * @throws \LogicException
     */
    protected function guessResource(): JsonResource
    {
        $resourceClass = $this->resolveResourceFromAttribute(static::class);

        if ($resourceClass !== null && class_exists($resourceClass)) {
            return $resourceClass::make($this);
        }

        foreach (static::guessResourceName() as $resourceClass) {
            if (is_string($resourceClass) && class_exists($resourceClass)) {
                return $resourceClass::make($this);
            }
        }

        throw new LogicException(sprintf('Failed to find resource class for model [%s].', get_class($this)));
    }

    /**
     * Guess the resource class name for the model.
     *
     * @return array{class-string<\Illuminate\Http\Resources\Json\JsonResource>, class-string<\Illuminate\Http\Resources\Json\JsonResource>}
     */
    public static function guessResourceName(): array
    {
        $modelClass = static::class;

        if (! Str::contains($modelClass, '\\Models\\')) {
            return [];
        }

        $relativeNamespace = Str::after($modelClass, '\\Models\\');

        $relativeNamespace = Str::contains($relativeNamespace, '\\')

View on GitHub (pinned to e0f6eb3518)