Problem/Motivation

When trying to save an unpublished node as a non-admin user, I get the error message "Either the path '/node/[nid]' is invalid or you do not have access to it.".

Steps to reproduce

  • Create a role with permissions to edit nodes.
  • As a user with that role, create a new node with a path alias
  • Edit the node again and remove the "Published" checkbox. Try to save.

Expected behaviour

The node gets saved.

Actual behaviour

Instead, I get the above error message.

It was assumed that this issue is related to #3101344: hook_node_grants implementations lead to a 'URL Alias' validation error when saving translated nodes. or might even be a duplicate, but as that one has been fixed since Drupal 10.2.3 and this issue still persists, there must be another cause.

Currently there are two known workarounds:

  • Grant the permission "link to any page" to the affected roles
  • Grant the permission "view any unpublished content" provided by the View Unpublished contrib module.
CommentFileSizeAuthor
#25 error.png17.53 KBheikkiy
#25 alias.png31.78 KBheikkiy

Issue fork drupal-3167732

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mrshowerman created an issue. See original summary.

pameeela’s picture

Issue tags: +Bug Smash Initiative

@mrshowerman, FWIW, 'View own unpublished content' will also get around this error for nodes that the user in question created.

Going to try to get a second opinion on whether to keep this open or close as a duplicate given that this exact issue is already mentioned in a comment on #3101344: hook_node_grants implementations lead to a 'URL Alias' validation error when saving translated nodes.. But as that issue is related to migration/upgrade, it is a little confusing.

mrshowerman’s picture

Thanks @pameeela, but "View own unpublished content" doesn't suffice in our case, as we want editors to be able to edit unpublished content of other users as well. AFAIK, there's no such permission as "View all unpublished content".

I did read the comment in #3101344: hook_node_grants implementations lead to a 'URL Alias' validation error when saving translated nodes. concerning my case and was hoping to find a solution there. But as the discussion in that issue went on in a different direction, I decided to create a separate issue. My case also happens in a fresh 9.0.3 installation, so I'm convinced it is not a migration issue.

pameeela’s picture

Yes it's definitely a core issue and does not require a migration to reproduce it. But the fix may be the same, in which case it's best to have all the effort going toward one issue.

I strongly suspect there is another duplicate as well, as this is just the type of issue that wouldn't go unreported, but I wasn't able to find anything else in a quick search.

larowlan’s picture

pameeela’s picture

I think that's the same issue as 'Link to any content' - it's too broad. Content edit permissions can be granted per bundle, so you could only want to give permission to view any unpublished content of the bundles the user has access to edit, rather than all unpublished content.

codersukanta’s picture

Non-admins user does not have permission to view the unpublished content causing the issue. Enabling content_moderation module and giving permission to view any unpublished content to Non-admin user will resolve the issue.

mrshowerman’s picture

@codersukanta it's not about viewing the unpublished content, but editing and saving it. This works for non-admins as long as the content does not have a path alias. If there is an alias, saving leads to the reported error.
Being allowed to edit an unpublished content should stay independent of the permission to view it, I think.

pameeela’s picture

Yeah I think the 'Link to any content' workaround is better (and much simpler) than enabling content moderation and adding 'View any unpublished content'.

The issue is that you may not want these users to be able to view *any* unpublished content. Just the content that they can edit.

codersukanta’s picture

@mrshowerman You are right but the content with path alias gone through a validation process while non-admin user edit and save the node.

The function checkAccess from core/lib/Drupal/Core/Routing/AccessAwareRouter.php file returns AccessDeniedHttpException in this case as non-admin user does not have permission to access the unpublished content ("node/[nid]").

if (!$access_result->isAllowed()) {
      if ($access_result instanceof CacheableDependencyInterface && $request->isMethodCacheable()) {
        throw new CacheableAccessDeniedHttpException($access_result, $access_result instanceof AccessResultReasonInterface ? $access_result->getReason() : NULL);
      }
      else {
        throw new AccessDeniedHttpException($access_result instanceof AccessResultReasonInterface ? $access_result->getReason() : NULL);
      }
    }

And if you check validate function from core/lib/Drupal/Core/Path/Plugin/Validation/Constraint/ValidPathConstraintValidator.php.
The $path variable in validate function seems to be a path of node view page.

Replacing $path variable to ("node/[nid]/edit") working fine as the non-admin users have access to the node edit page.

mrshowerman’s picture

I came across the same method after spending hours in the debugger. The $access_result that is being checked is an instance of AccessResultNeutral and calling isAllowed returns false, thus leading to the Exception being thrown.

I think the core cause is the fact that the path is being validated at all when saving a node; I think this shouldn't happen in this situation, but only when the node is really being viewed.

sundays’s picture

I can confirm #10 and #11 findings.
As a fix, what I did was adding a node_access hook like this so that managers (a role) could save any node of type project:

// implements hook_node_access
function mymodule_node_access(NodeInterface $node, $op, AccountInterface $account) {
  // allow managers edit any project (even unpublished and not theirs)
  if (in_array($op, ['view', 'update']) && $node->bundle() == 'project' && in_array('manager', $account->getRoles())) {
    return AccessResult::allowed();
  }
}
knowak’s picture

I'm coming across the same issue as #10 and #11 describes but it is happen with content in a Group using the Group module with the Group permission 'Relation: View any entity relations'. The user has permission to edit the content but not to view the group content relation path that is being validated.

We are using content moderation and this is only a problem when the content is in draft (unpublished). The users have the 'View any unpublished content' content moderation permission. Once the content is published the user can save and change states with no issue. User can also change the state and save in layout builder with no issue.

The 'link to any page' permission works as a workaround for me also.

alphex’s picture

I'm seeing this same issue, just keeping the thread alive.

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

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
francescoq’s picture

I can confirm the same issue here (D8)

I used the workaround in #12 but in a more generic way:

  if (in_array($operation, ['update']) && $account->hasPermission('edit any ' . $entity->bundle() . ' content')) {
    return AccessResult::allowed();
  }

since if a user can update any content of that type... it should be able to update all the contents of that type :D

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

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Mayankkumar Jeshti’s picture

#17 works perfectly.. Thanks @FrancescoQ

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

aswathyajish’s picture

I had the same issue in drupal core 10.2.4. I tried #7 and it saved my day. Thanks a lot.

anybody’s picture

anybody’s picture

Just ran into this and as written in https://www.drupal.org/project/drupal/issues/2809177#comment-15721147 this is a really weird buggy situation which should be resolved in core soon. Blocked by #273595: Move permission "view any unpublished content" from Content Moderation to Node which is blocked by #2809177: Introduce entity permission providers!

heikkiy’s picture

StatusFileSize
new31.78 KB
new17.53 KB

We are encountering this issue after updating to Drupal core 10.3.6.

We have disabled that certain roles can add content to menus and edit the path alias. This has been working before but after the update they cannot save nodes. It seems like the alias is not updating soon enough and it gives an error.

From the attached screenshots it's visible that the alias is correct but it's giving an error the original node ID alias.

If I give the Link to any page permission to the affected role it starts to work.

heikkiy’s picture

A small update related to our issue after updating to 10.3. The permission change for Link to any page did solve the problem but was probably not the original issue. While digging deeper I started to remove all core patches we had for 10.2 and finally arrived to removing the patch from issue #2557469: Route validation does not preserve request method, defaults to GET and that seemed to fix the problem. It seems like that issue might be outdated and is already fixed in a separate issue.

After removing that patch I was able to save the translations without the permission change.

mxr576’s picture

#3101344: hook_node_grants implementations lead to a 'URL Alias' validation error when saving translated nodes. should have fixed this, or should not? 10.2.3 is the first release with that fix.

heikkiy’s picture

Indeed. That problem should have fixed the issue so I am not 100% sure why it now surfaced for us with 10.3.6. Looking at issue #2557469: Route validation does not preserve request method, defaults to GET and the patch #30 it seems to alter how the AccessAwareRouter works. Perhaps there was some change in in 10.3.x that caused the patch to work wrong.

Anyway I agree this issue needs summary and status update because it seems like #3101344: hook_node_grants implementations lead to a 'URL Alias' validation error when saving translated nodes. should have fixed the issue.

mrshowerman’s picture

Issue summary: View changes

I made a few tests on several of our sites using different versions of Drupal (9.5.11, 10.2.0, 10.2.5, 10.2.7, and 10.3.6). All of them show the same error message when saving an unpublished node that has a URL alias. So I can confirm that #3101344: hook_node_grants implementations lead to a 'URL Alias' validation error when saving translated nodes. did not fix the issue.

I noticed that there is a second workaround: granting the "view any unpublished content" (provided by the View Unpublished module) also fixes the issue.

Updated the IS accordingly.

heikkiy’s picture

I can also confirm that we have View unpublished contrib module installed in our project. But still notable that the setup was working fine in 10.2.x branch. Verified that we were running 10.2.7 before updating to 10.3.6. And after that update non-admins started to receive that error message when saving translations. Removing the patch from issue #2557469: Route validation does not preserve request method, defaults to GET solved the issue.

mxr576’s picture

I think it should be fairly simple setting up a failing test in this issue as a next step. That should also eliminate questions like which contribs or other Drupal patches were contributed to this problem on this and that project.

Based on what I have read so far my Spidey-senses say that the issue could be related to hook_node_grants()/hook_node_access_records() because when an node access module (like view_unpublished) is enabled then access control logic applied to nodes changes "drastically" on a site. Nodes that the current user does not have (view) access gets filtered out from query results so Node::load()/Node::loadMultiple() does not even get those to load. The current repro steps also does not say anything about whether the given user had _view_ access to the unpublished node or not, it just say they had edit access, which is an other clue for me, especially since I was investigated node access related wtf for a long time (#3452449: Grant query level access to own/any unpublished nodes).

Steps to reproduce
* Create a role with permissions to edit nodes.
* As a user with that role, create a new node with a path alias
* Edit the node again and remove the "Published" checkbox. Try to save.

heikkiy’s picture

At least in our case the user role does have the View unpublished content for the problematic content type. They do not have the permission View any unpublished content. They also have the edit permission so they are able to open the node edit route. I was able to open the unpublished node in view mode but the editing was blocked by the error.

Adding the needed tests for this seems like the logical next step.

mxr576’s picture

I was able to open the unpublished node in view mode, but attempting to edit it triggered the error.

This behavior is indeed possible because the entity parameter converter basically relies on `Node::load()` with the given node ID, rather than performing an entity query that would respect query-level access control (`node_access`). Specifically, entity access handler and even `hook_entity_access()` implementation can grant access to a node even if hook_node_grants()/hook_node_access_records() does not. In practice, permissions like "view own/any unpublished node" are evaluated earlier than node access checks. If access is granted at this stage, node acess won’t be called.

And I assume the path based access checking relies on entity query... but I haven't checked.

vesnag made their first commit to this issue’s fork.

vesnag’s picture

Manual steps to reproduce this issue with 11.1.0-dev

Module Configuration:
- The 'Content Moderation Workflows' module should not be enabled.
- The 'Workflow' module should be enabled.

Content Type Setup:
For the 'Article' content type, navigate "admin/structure/types/manage/article" to the "Publishing options". For the "Default options" ensure that 'Published' is unchecked.

Role Permissions:
- The 'Content editor' role should have the 'View published content' permission.
- The 'Content editor' role should have the 'Article: Edit own content' permission set.
- The 'Content editor' role should not have the 'View own unpublished content' permission set.

Steps and access :
- Create a user with the 'Content editor' role.
- Create an Article node with a custom URL alias.
- When accessing 'node/X' as a user with the 'Content editor' role, an 'Access denied' message should be displayed.
- When accessing 'node/X/edit' as a user with the 'Content editor' role, an edit form should be presented.
- When attempting to save the content of this node again, the user should receive the error message: "Either the path '/node/X' is invalid or you do not have access to it."

Additional Considerations:
Test user should not have additional permissions that could mask the issue: The 'Link to any page' and 'View any unpublished content' permissions should not be granted.

A functional test was implemented to address this issue:
https://git.drupalcode.org/issue/drupal-3167732/-/blob/3167732-non-admin...

It would be nice if someone could provide feedback on this failing test to confirm if continuing in this direction is recommended.

Thank you!

rajeevkumar’s picture

Only installing the Pathauto module is removing this blocker and non-admin user can do the regular URL alias updates and creation. (But Core fix is recommended.)

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.