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

Comments

sourabh05 created an issue. See original summary.

sourabhbhalerao’s picture

Title: UnexpectedValueException: External URLs do not have an internal route name. in Drupal\Core\Url->getRouteName() » UnexpectedValueException: External URLs do not have an internal route name. in Drupal\Core\Url->getRouteName() (line 555 of C:\xampp\htdocs\Fei_live\core\lib\Drupal\Core\Url.php)
sourabhbhalerao’s picture

Assigned: sourabhbhalerao » Unassigned
cilefen’s picture

Priority: Normal » Major
Status: Active » Needs work

Interesting...this may have been reported in the past but I haven’t yet looked.

nikitas’s picture

Hi 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

 vendor/bin/drupal router:debug

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

    // Logs as errors
    \Drupal::logger('HELPPPP')->error($this->getUri());

Now after this i had this in my admin/reports/dblog Bug
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

  • old_5df252_url_alias (table)
  • in a link field table i have in a content type and
  • in the revisions field table of the previous link field.

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.
wrong internal path

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

      throw new \UnexpectedValueException('External URLs do not have an internal route name. See this '.$this->getUri());

instead of

      throw new \UnexpectedValueException('External URLs do not have an internal route name.');

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 :) ).

Version: 8.5.3 » 8.5.x-dev

Core issues are now filed against the dev versions where changes will be made. Document the specific release you are using in your issue comment. More information about choosing a version.

Version: 8.5.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Branches prior to 8.8.x are not supported, and Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

johan den hollander’s picture

Thanks @Nikitas your suggestion helped me find that I had some absolute paths in my database after migrating a D7 site to D9.

nwom’s picture

Version: 8.9.x-dev » 9.0.x-dev
Status: Needs work » Active

I can confirm that this is still an issue in D9.08 as well. Setting to Active though, since no patch is attached.

seanb’s picture

It 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.

Version: 9.0.x-dev » 9.1.x-dev

Drupal 9.0.10 was released on December 3, 2020 and is the final full bugfix release for the Drupal 9.0.x series. Drupal 9.0.x will not receive any further development aside from security fixes. Sites should update to Drupal 9.1.0 to continue receiving regular bugfixes.

Drupal-9-only bug reports should be targeted for the 9.1.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.2.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

alexmoreno’s picture

this 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

gaurav.kapoor’s picture

Version: 9.1.x-dev » 9.3.x-dev
gaurav.kapoor’s picture

StatusFileSize
new558 bytes

This 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.

joachim’s picture

I think this is related to the same problem I am seeing:

    $url = Url::fromUri("internal:/path-doesnt-exist");
    dump($url->isRouted());

     $route_parameters = $url->getRouteParameters();

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:

    $url = \Drupal::pathValidator()
      ->getUrlIfValidWithoutAccessCheck($uri_parts['path']) ?: static::fromUri('base:' . $uri_parts['path'], $options);

There needs to be a check somewhere for 'did this get a URL object which is internal?'

ghost of drupal past’s picture

Title: UnexpectedValueException: External URLs do not have an internal route name. in Drupal\Core\Url->getRouteName() » Improve error message on unrouted URLs
Issue summary: View changes
ghost of drupal past’s picture

Component: path.module » base system
Category: Bug report » Task
ghost of drupal past’s picture

Issue summary: View changes

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

nwom’s picture

Status: Active » Needs work

Setting to Needs Work, since a patch is attached, however there are still issues mentioned in #15.

moshe weitzman’s picture

Status: Needs work » Needs review

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.

yogeshmpawar’s picture

StatusFileSize
new560 bytes
new586 bytes

Resolved CSpell errors

pmichelazzo’s picture

Thanks 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

moshe weitzman’s picture

Status: Needs review » Reviewed & tested by the community

Passes tests, and makes usability better.

joachim’s picture

> 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.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Thanks 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:

>>> $a = \Drupal\Core\Url::fromUri('https://www.drupal.org');
=> Drupal\Core\Url {#4673}
>>> $a->getRouteName();
UnexpectedValueException with message 'External URLs do not have an internal route name. See this https://www.drupal.org'

The See this https://www.drupal.org does 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.

ghost of drupal past’s picture

the problem typically does not occur with external urls rather this way:

  1. add a link to an existing page, it'll be stored with internal:
  2. delete the page
  3. Your code which worked before the page delete now fatals.
andregp’s picture

Status: Needs work » Needs review
StatusFileSize
new560 bytes

I 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.

alexpott’s picture

@andregp if you use drush php on an install Drupal you'll get a repl in a bootstrapped Drupal so it'll work like this:

>>> $a = \Drupal\Core\Url::fromUri('internal:/foo/bar');
>>> $a->getRouteName();
UnexpectedValueException with message 'base:foo/bar is an external URL and cannot have an internal route name.'

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.');

ghost of drupal past’s picture

Edit: ah nevermind, alexpott actually addressed my concern. Great!

andregp’s picture

StatusFileSize
new529 bytes

@alexpott Thanks for the tip.

ghost of drupal past’s picture

Status: Needs review » Reviewed & tested by the community

Looks great.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 83e1686b69 to 10.0.x and 4da04a22c4 to 9.4.x. Thanks!

  • alexpott committed 83e1686 on 10.0.x
    Issue #3013802 by andregp, yogeshmpawar, gaurav.kapoor, nikitas, Charlie...

  • alexpott committed 4da04a2 on 9.4.x
    Issue #3013802 by andregp, yogeshmpawar, gaurav.kapoor, nikitas, Charlie...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.