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 guessResourceCollection() as the final fallback when no resolvable resource class was found. After checking the UseResourceCollection attribute, the UseResource attribute, and the class::guessResourceName() list (appending 'Collection' and testing class_exists on each), if none of the candidate classes exist it throws LogicException naming the model class.

Solutions

  1. Verify the resource class name returned by guessResourceName matches an existing autoloaded class.
  2. Ensure the 'XCollection' variant exists if the guesser tries it, or add a UseResource attribute pointing to a real class.
  3. Pass the resource class explicitly to bypass guessing: ->toResourceCollection(MyResource::class).

Example fix

// before
// guessResourceName() returns ['App\Http\Resources\Order'] but class is OrderResource
// after
return ['App\Http\Resources\OrderResource'];  // correct class name
Defensive patterns

Strategy: validation

Validate before calling

$first = $collection->first();
$candidates = $first::guessResourceName();
foreach ($candidates as $c) {
    if (class_exists($c) || class_exists($c.'Collection')) {
        // safe to guess
    }
}
return $collection->toResourceCollection();

Type guard

function resourceClassResolvable(string $modelClass): bool {
    if (! method_exists($modelClass, 'guessResourceName')) return false;
    foreach ($modelClass::guessResourceName() as $r) {
        if (class_exists($r) || class_exists($r.'Collection')) return true;
    }
    return false;
}

Try / catch

try {
    return $collection->toResourceCollection();
} catch (\LogicException $e) {
    return $collection->toResourceCollection(\App\Http\Resources\DefaultResource::class);
}

Prevention

When it happens

Trigger: Model uses TransformsToResource and guessResourceName returns class names, but none of those classes (or their 'Collection' variants) are autoloadable; a typo in the resource class name returned by guessResourceName; the resource file was deleted/renamed.

Common situations: Renaming a resource class without updating guessResourceName; namespace mismatch between the model's guess and the actual resource location; missing composer dumpautoload after adding the resource.

Related errors


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

Appendix: source

Thrown at src/Illuminate/Collections/Traits/TransformsToResourceCollection.php:85

        }

        $resourceClasses = $className::guessResourceName();

        foreach ($resourceClasses as $resourceClass) {
            $resourceCollection = $resourceClass.'Collection';

            if (is_string($resourceCollection) && class_exists($resourceCollection)) {
                return new $resourceCollection($this);
            }
        }

        foreach ($resourceClasses as $resourceClass) {
            if (is_string($resourceClass) && class_exists($resourceClass)) {
                return $resourceClass::collection($this);
            }
        }

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

    /**
     * Get the resource class from the class attribute.
     *
     * @param  class-string<\Illuminate\Http\Resources\Json\JsonResource>  $class
     * @return class-string<*>|null
     */
    protected function resolveResourceFromAttribute(string $class): ?string
    {
        if (! class_exists($class)) {
            return null;
        }

        $attributes = (new ReflectionClass($class))->getAttributes(UseResource::class);

        return $attributes !== []
            ? $attributes[0]->newInstance()->class

View on GitHub (pinned to e0f6eb3518)