It appears that when a single entity instance lacks a UUID, trying to get a listing of that entity type via JSON API leads to a 500 internal server error that results from a Symfony\Component\Routing\Exception\InvalidParameterException
that seems to come out of nowhere. The exception message isn't particularly helpful.
<!--break-->
Here's the full exception + stack:
Symfony\Component\Routing\Exception\InvalidParameterException: Parameter "entity" for route "jsonapi.my_entity--my_entity.individual" must match "[^/]++" ("" given) to generate a corresponding URL. in /core/lib/Drupal/Core/Routing/UrlGenerator.php:204
Stack trace:
#0 core/lib/Drupal/Core/Routing/UrlGenerator.php(251): Drupal\Core\Routing\UrlGenerator->doGenerate(Array, Array, Array, Array, Array, 'jsonapi.my_entit...')
#1 core/lib/Drupal/Core/Routing/UrlGenerator.php(293): Drupal\Core\Routing\UrlGenerator->getInternalPathFromRoute('jsonapi.my_entit...', Object(Symfony\Component\Routing\Route), Array, Array)
#2 core/lib/Drupal/Core/Render/MetadataBubblingUrlGenerator.php(105): Drupal\Core\Routing\UrlGenerator->generateFromRoute('jsonapi.my_entit...', Array, Array, true)
#3 core/lib/Drupal/Core/Url.php(753): Drupal\Core\Render\MetadataBubblingUrlGenerator->generateFromRoute('jsonapi.my_entit...', Array, Array, true)
#4 core/modules/jsonapi/src/JsonApiResource/Link.php(83): Drupal\Core\Url->toString(true)
#5 core/modules/jsonapi/src/JsonApiResource/ResourceObject.php(258): Drupal\jsonapi\JsonApiResource\Link->__construct(Object(Drupal\Core\Cache\CacheableMetadata), Object(Drupal\Core\Url), Array)
#6 core/modules/jsonapi/src/JsonApiResource/ResourceObject.php(111): Drupal\jsonapi\JsonApiResource\ResourceObject::buildLinksFromEntity(Object(Drupal\jsonapi\ResourceType\ResourceType), Object(Drupal\external_entities\Entity\ExternalEntity), Object(Drupal\jsonapi\JsonApiResource\LinkCollection))
It looks like this comes from this portion of \Drupal\jsonapi\JsonApiResource\ResourceObject::buildLinksFromEntity
:
protected static function buildLinksFromEntity(ResourceType $resource_type, EntityInterface $entity, LinkCollection $links) {
if ($resource_type->isLocatable() && !$resource_type->isInternal()) {
$self_url = Url::fromRoute(Routes::getRouteName($resource_type, 'individual'), ['entity' => $entity->uuid()]);
// ...
}
// ...
}
// ...
It would be great if there was a sanity check that $entity->uuid()
is not empty. Then a more appropriate exception/error message could be thrown instead.
Additional Context
We are using
External Entities β
to wrap data from an external API as entities within our Drupal installation. External Entities allows us to map a value from the external service into the UUID field of entities, but it's not a required field. Since we have some values without UUIDs populated in the other service, we ran into the exception indicated above.