Error: Resource URI already exists while using resource/update processor

I’m updating (and creating) resources through a snippet with the resource/ create/update processor but for one resource I get the error Resource URI already exists for resource id 1503.

I update/generate the resources (and the alias) based on data from a csv file and I combine name and an individual sku number so the alias is never the same (I double checked for duplicates):

if ($resource) {

  $modx->runProcessor('resource/update', [
    'id' => $resource->get('id'),
    'class_key' => 'modDocument',
    'context_key' => 'web',
    'parent' => $resourceParentId,
    'pagetitle' => $data['name'],
    'alias' => $modx->filterPathSegment($data['name'] . '-' . $data['sku']),
    'published' => true,
  ]);

The interesting part is, that the resource 1503 which claims to already own the URI it’s trying to set, is the parent of that resource. So my thinking is that maybe there’s an issue while generating the alias and filterPathSegment returns nothing so a blank alias would result in the same URI as its parent?

Are there maybe any characters for example that filterPathSegment can’t deal with?

So what is the exact value that $modx->filterPathSegment() is called with?
Maybe you can create a test snippet with the hard-coded value to see what gets returned (or log the value during the import).

And why does the parent resource have no alias?

I logged it:
Fiamma Gelenkarm 320 – 450 ab sn. 9431697 für Markise F80S-6000105200

It does have an alias, I meant that if the alias of the resource that I’m trying to import is empty, it equals the URI of its parent. Therefore the error which is exactly the URI of the parent:

resource 1503 is already using the URI 'shop/ersatzteile/fuer-markisen/'

I assume this is the value before you call filterPathSegment().
I tested it in a snippet, but on my system this doesn’t return an empty value.

<?php
return $modx->filterPathSegment("Fiamma Gelenkarm 320 – 450 ab sn. 9431697 für Markise F80S-6000105200");

When you check the column alias in the database table modx_site_content for this resource, is the alias indeed a empty string? What is the value of the column uri?

Yes.

I guess I could’ve checked this before, no the alias is not empty:

alias:
fiamma-gelenkarm-320-–-450-ab-sn.-9431697-für-markise-f80s-6000105200

uri:
produkte/fiamma-gelenkarm-320-–-450-ab-sn.-9431697-für-markise-f80s-6000105200

So the alias looks correct (although I would like it to remove dots . as well).
The uri is generally also fine but should be getting updated as the parent of the resource changed to the resource with the alias fuer-markisen. After a successful import I would expect the uri to be:

shop/ersatzteile/fuer-markisen/fiamma-gelenkarm-320-–-450-ab-sn.-9431697-für-markise-f80s-6000105200

I’m a bit confused:
The error message “Resource URI already exists for resource …” occurs, when the aliasMap in the cache gets created. But as far as I can tell, the code just uses the values directly from the uri column.


So are there duplicate uri values in the database?
You could check with an SQL query like this:

SELECT id, alias, uri, context_key 
FROM `modx_site_content` SC
WHERE EXISTS (SELECT id FROM `modx_site_content` WHERE uri = SC.uri AND context_key = SC.context_key AND id <> SC.id )
ORDER BY uri;

Your suggested query gives an empty result, so I guess there are no duplicates.

I guess if there are no other ideas, I could try manually adjusting the resources parent through the manager or even directly in the db, but in case that works, there’s probably no way of telling what the issue originally was…

So I tried manually changing the parent of the resource in the manager and I got the same error, prompting me to change the alias. I tested a bit more and it seems that the issue is the En/Em dash () in the name.

From my testing it doesn’t matter where in the alias this character is, it will always through the error, despite any other character changes. As soon as it’s removed though, the resource saves fine.

I also tried creating a new resource with this character in it’s alias and it will also through the error. If created under a different parent, the error will claim this (different) parent to be the issue.

Still doesn’t make any sense to me, but maybe a hint in the right direction?

I can’t reproduce this problem.
An En/Em dash () in the alias doesn’t create any issues on my system.

What versions of MODX/PHP are you using?

MODX 2.8.5
PHP 8.2.4

Maybe it has something to do with the data coming from a .csv file? For now I fixed it with a string replace:

filterPathSegment(str_replace(["-", "–"], '', $data['name']) ...

I also noticed that previously the alias and uri contained a dot (.) which is not the case anymore after I removed the En dash. So I’m still wondering if there’s something going on with the filterPathSegment filter.

The exact behaviour of this function is defined by many system settings (e.g.
friendly_alias_restrict_chars_pattern). Do you use translit (setting friendly_alias_translit)?

But if you haven’t changed these settings, then the result shouldn’t change either.

What’s the system setting use_frozen_parent_uris set to?

It looks like I changed that (not recently but in early february). Forgot about that

/[\0\x0B\t\n\r\f\a&=+%#<>\.\/"~:`@\?\[\]\{\}\|\^’\\]/

default:
/[\0\x0B\t\n\r\f\a&=+%#<>"~:`@\?\[\]\{\}\|\^'\\]/

So I added \.\/ to actually remove dots and forward slashes but I don’t think that would cause the error?


It is set to No.

Hmm, maybe you can check what fields/values an update via the manager sends to the processor. Maybe you need to provide additional values as well. Maybe alias_visible set to 1 and uri set to an empty value.

I’m not sure if that would help, as it worked for literally hundreds of other resources which were imported and/or updated this way and it works if I replace the En dash so I don’t think adding any additional values is much useful or why should that be?