We are experiencing some strange behavior on our Drupal 8 website with url aliases.

All our nodes in the site have automatically generated URL aliases based on a pattern.
From time to time, a node loses its URL alias making it only accessible via /node/id. When we edit such a node, the checkbox for automatically generating an alias is still checked, but there's no value there. And when we save the node, the alias is regenerated and the problem seems to be fixed. But then the same happened to other nodes on other moments, and it keeps happening.

I haven't managed to reproduce the problem since I don't know what triggers it. I have tried several things, none seem to work.
For these faulty nodes, the URL aliases are no longer in the database (or never have been there).

Our client tells us it also happens to nodes that haven't been touched in weeks.

I'm using Pathauto 8.x-1.0-beta1 and Drupal 8.2.3.

Does anyone have an idea what might be happening?

Comments

screon created an issue. See original summary.

screon’s picture

Priority: Normal » Major

So I found the problem...
Whenever you delete some node, nodes with similar IDs will lose their alias. Here's why:

In the AliasStorageHelper there is this function (I moved the query into a variable while debugging):

  public function loadBySourcePrefix($source) {
    $query = $this->database->select('url_alias', 'u')
                            ->fields('u', array('pid'))
                            ->condition('source', $source . '%', 'LIKE')
                            ->execute()
                            ->fetchCol();

    return $query;
  }

The $source contains a string, e.g. for nodes: /node/10

The condition on the query turns this into /node/10%, thus effectively selecting all nodes which start with nid "10": /node/100, /node/101, ... And by that deleting all the aliases for these nodes in deleteSourceByPrefix().

I checked an older project using an older version of pathauto, there the function is different:

  public function loadBySourcePrefix($source) {
    return $this->database->query("SELECT pid FROM {url_alias} WHERE source = :source OR source LIKE :source_wildcard",
      [':source' => $source, ':source_wildcard' => $source . '/%'])
      ->fetchCol();
  }

In this version there's a slash in front of the wildcard, making the query only select /node/10 and /node/10/% which works correctly.

It seems the bug was introduced by a typo when refactoring.

Berdir’s picture

Ouch, nice find!

Can you provide a patch and maybe a test for this?

screon’s picture

Here's a patch.

I followed the logic of the previous version, with an orConditionGroup I check for /node/[nid] and /node/[nid]/%.
The same query was being used in countBySourcePrefix() so I updated that part as well.

Could you give me a hand on the test, or point me in the right direction? Not sure on how to do that.

screon’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, 4: automatic_url_aliases-2831697-4.patch, failed testing.

The last submitted patch, 4: automatic_url_aliases-2831697-4.patch, failed testing.

Berdir’s picture

See \Drupal\Tests\pathauto\Kernel\PathautoKernelTest::testPathDeleteMultiple(). I think you just need to add a few more cases there that we don't want to get deleted and assert that they still exist.

Also looks like something with the mass delete test isn't quite right yet?

webflo’s picture

@screon Great work! I got the same client complaints, but could not reproduce it.

Added a new alias and assertion to PathautoKernelTest::testPathDeleteMultiple (2831697-9-testonly.patch should fail) and fixed the condition by adding a rtim, because the return value of EntityAliasTypeBase::getSourcePrefix contains a slash already.

The last submitted patch, 9: 2831697-9-testonly.patch, failed testing.

The last submitted patch, 9: 2831697-9-testonly.patch, failed testing.

  • Berdir committed fe94904 on 8.x-1.x authored by screon
    Issue #2831697 by webflo, screon: Automatic url aliases disappearing...
Berdir’s picture

Status: Needs review » Fixed

Thanks. Moved the first condition() call to a separate line and committed.

screon’s picture

Great! Webflo, thanks for the help :)

LpSolit’s picture

This seems a pretty severe issue. Any chance to have a new release (beta2) soon?

Status: Fixed » Closed (fixed)

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

SchnWalter’s picture

I think that this is a big enough problem that it should warrant an immediate beta release. If you have a site with a large number of entities, it is guaranteed that you are going to run into this issue.

Thank you!

ressa’s picture

I think that this is a big enough problem that it should warrant an immediate beta release.

I agree, my client was just hit by this, it would be great to get an official release with this problem fixed.

Berdir’s picture

I released 8.x-1.0-beta2 now.

ressa’s picture

Thanks! In 8.x-1.0-beta2 URL aliases are no longer deleted upon deletion of a specific node.