[5.x]: Team group saved without name and handle, so project-config/apply fails

Open Beginner friendly
#20,595 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@brandonkelly is already working on this.

Since Nov 12, 2026.

  • #20625 by @brandonkelly — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
66/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
php
Domain
backend, database

Research direction

Start by reading UserGroups::getTeamGroup(), UserPermissions::saveGroupPermissions(), and UserGroups::handleChangedUserGroup(); the issue identifies the missing name and handle in project config as the failure. Reproduce with the supplied craft exec steps, then run php craft project-config/apply --force to check the reported failure is resolved and the Team group config includes both fields.

Written by the indexing model from the issue text.

Description

bug repo:cms
What happened?
Description

On Craft 5.12.1 (Team), UserGroups::getTeamGroup() creates the Team group in the database only, not in the project config. It's also called from User::afterSave(). If permissions are then saved with UserPermissions::saveGroupPermissions(), the project config gets users.groups.<uid> with only permissions. The next project-config/apply (for example during a deploy) then fails.

Saving the Team permissions in Settings → Users is fine, because the controller calls saveGroup() first.

Steps to reproduce
  1. On a Team install, run this with craft exec:

    $pc = Craft::$app->getProjectConfig();
    $pc->remove('users.groups.c55ca0a9-4bd6-409b-afd8-c1884dafecd0'); // fresh state: no Team group
    $group = Craft::$app->getUserGroups()->getTeamGroup();
    Craft::$app->getUserPermissions()->saveGroupPermissions($group->id, ['viewusers']);
    

    The remove() simulates a Team install where the group exists only in the database.

  2. Look at config/project/users/groups/<uid>.yaml: it only has permissions.

  3. Run php craft project-config/apply --force.

Expected behavior

The Team group in the project config always has its name and handle, for example because getTeamGroup() saves the group through saveGroup(), or because saveGroupPermissions() makes sure the group exists in the project config. project-config/apply succeeds.

Actual behavior

project-config/apply fails with Undefined array key "name" in UserGroups::handleChangedUserGroup() (UserGroups.php:347).

Craft CMS version

5.12.1 (Team)

PHP version

8.5.12

Operating system and version

Debian GNU/Linux 13 (trixie), DDEV

Database type and version

MySQL 8.0.46

Image driver and version

Imagick 3.8.1 (ImageMagick 7.1.1-43)

Installed plugins and versions
Dominant language
PHP
Stars
3.6k
Forks
714
Avg merge
13h 20m
Merged PRs (30d)
471

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from craftcms/cms

All issues in craftcms/cms

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.