Problem/Motivation
A link pointing to an entity after deleting said entity will most likely become unrouted and calling $url->getRouteName() (or $url->getRouteParameters()) for an unrouted url gives an inscrutable error message: UnexpectedValueException: External URLs do not have an internal route name..
Steps to reproduce
I believe this is not reproducible with core, it needs custom code. But Url::fromURI('internal:/foo/bar')->getRouteName() will most likely do it. The link widget uses internal: which eventually leads to this:
$url = \Drupal::pathValidator()
->getUrlIfValidWithoutAccessCheck($uri_parts['path']) ?: static::fromUri('base:' . $uri_parts['path'], $options);
so the returned Url object can be routed or unrouted -- and it changes somewhat unexpectedly.
Proposed resolution
https://github.com/mglaman/phpstan-drupal/issues/257 and also improve the error message to include the URL and indicate it became unrouted.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Original report by SourabhBhalerao
Steps for reproduce this issue :-
1. Create one node with url alias.
2. Create menu and put above node url alias in menu path.
3. Delete Path alias from url alias configuration.
4. Then go to fronted of website then it give white screen with error message.
Thanks
| Comment | File | Size | Author |
|---|---|---|---|
| #31 | 3013802-31.patch | 529 bytes | andregp |
| #28 | 3013802-28.patch | 560 bytes | andregp |
| #22 | interdiff-3013802-14-22.txt | 586 bytes | yogeshmpawar |
| #22 | 3013802-22.patch | 560 bytes | yogeshmpawar |
| #14 | external-url.patch | 558 bytes | gaurav.kapoor |
Comments
Comment #2
sourabhbhalerao commentedComment #3
sourabhbhalerao commentedComment #4
cilefen commentedInteresting...this may have been reported in the past but I haven’t yet looked.
Comment #5
nikitas commentedHi i had the same issue but in my case i did not know what was deleted (a node or view or taxonomy or view page path) because i was not the user that deleted the node and this showed up only after clearing the caches.
So at first I tried using drupal console to see the available routes
but this was not helpful because i was missing a node path.
Now the real question here, is how do you find what are you missing? I had to Log somehow the uri that was creating the white screen of death. So i edited
/web/core/lib/Drupal/Core/Url.php and added at line: 556
Now after this i had this in my admin/reports/dblog
So what i did was to create a new dummy node and add the path alias node/109 for my new dummy node.
The only issue with that was that if i would delete my dummy node then 'boom' my frontpage would break again.
So I searched my files in case there was a node/109 path somewhere (in cache files) but with no luck. So i thought that maybe i am missing something else here because my base path node:109 should exist somewhere. This is where i made a dump sql backup of my db and searched for my missing path node/109 and there it was everywhere.
If found it in
So there it was in 3 tables. Now, i knew exactly where to find my missing node path (it was a link field of another content type that was linking to my old deleted path).

After i replaced /node/109 with my path /taxonomy/term/[tid] everything was working again.
I hope that helps someone in the future.
Maybe a good solution for this would be to update web/core/lib/Drupal/Core/Url.php and at line: 556 and add
instead of
It is more user friendly and will save a lot of "debugging" time of new drupal 8 developers like me :) in the future.
If this happens again (if you have a link field in an entity type that links to another node that is deleted, i will be in trouble again :) ).
Comment #8
johan den hollander commentedThanks @Nikitas your suggestion helped me find that I had some absolute paths in my database after migrating a D7 site to D9.
Comment #9
nwom commentedI can confirm that this is still an issue in D9.08 as well. Setting to Active though, since no patch is attached.
Comment #10
seanbIt would already really help if the exception in getRouteParameters() and getRouteName() could add some information about the url having the problem. We currently have a complex node with paragraphs etc. Editors are currently not able to find the problematic link and correct it themselves.
Comment #12
alexmoreno commentedthis probably should not break in production, but instead log critical errors. This was breaking for us in production because a field did not have the right url. If the user is not able to see click on a deep link on a given page is bad, but if there is a 503 error is even worse :-D
I'll see if I can push/propose something
Comment #13
gaurav.kapoor commentedComment #14
gaurav.kapoor commentedThis issue exists even when a user enters a URL like '/node/345' or '/example-alias' in the URL autocomplete field. Adding a patch based on suggestions in #5 to make debugging easier, till the time a permanent fix is in place.
Comment #15
joachim commentedI think this is related to the same problem I am seeing:
which throws 'External URLs do not have internal route parameters'.
This exception is unclear -- it's not an external URL, it's a URL which has been set with the 'base:' scheme because no route was found:
There needs to be a check somewhere for 'did this get a URL object which is internal?'
Comment #16
ghost of drupal pastComment #17
ghost of drupal pastComment #18
ghost of drupal pastComment #20
nwom commentedSetting to Needs Work, since a patch is attached, however there are still issues mentioned in #15.
Comment #21
moshe weitzman commentedThe most recent patch doesn't attempt to improve the error message, so #15 doesn't apply. The patch just gives more debug info, which is very helpful. IMO its not worth holding back an improvement any longer.
Comment #22
yogeshmpawarResolved CSpell errors
Comment #23
pmichelazzoThanks for the tip @nikitas about your comment at #5
I had a problem with a menu today and your trick help me a lot.
Best
Comment #24
moshe weitzman commentedPasses tests, and makes usability better.
Comment #25
joachim commented> The most recent patch doesn't attempt to improve the error message, so #15 doesn't apply. The patch just gives more debug info, which is very helpful. IMO its not worth holding back an improvement any longer.
I don't understand.
The issue title is about improving the error message. What does the RTBC'd patch do if not that?
Should #15 be dealt with in another issue then? I thought it seemed closely related to this.
Comment #26
alexpottThanks for working on this issue. I think if we are changing the message then is needs to make sense. I'm not sure that
External URLs do not have an internal route name. See this ' . $this->getUri()actually helps that much.If I cause this exception this is what I see:
The
See this https://www.drupal.orgdoes not make any sense.I think
throw new \UnexpectedValueException($this->getUri() . ' is an external URL and cannot have an internal route name.');is an improvement but perhaps people have a better idea.Comment #27
ghost of drupal pastthe problem typically does not occur with external urls rather this way:
Comment #28
andregp commentedI was able to reproduce the error thanks to @alexpott's code on #26.
Here is the new patch with his suggested message.
Also, I don't know if it's relevant to the issue, but when I run getRouteName() with an internal link (like
'internal:/foo/bar'as suggested in the IS, or even an existing one) I get a completely different error:Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "path.validator".I'm not sending an interdiff as the patch alters only one line.
Comment #29
alexpott@andregp if you use
drush phpon an install Drupal you'll get a repl in a bootstrapped Drupal so it'll work like this:Which also makes me question the correctness of this message. Perhaps that most simple thing would be to change the message to:
throw new \UnexpectedValueException($this->getUri() . ' has no corresponding route.');Comment #30
ghost of drupal pastEdit: ah nevermind, alexpott actually addressed my concern. Great!
Comment #31
andregp commented@alexpott Thanks for the tip.
Comment #32
ghost of drupal pastLooks great.
Comment #33
alexpottCommitted and pushed 83e1686b69 to 10.0.x and 4da04a22c4 to 9.4.x. Thanks!