toeverything/AFFiNE · error · DocDefaultRoleCanNotBeOwner
doc_default_role_can_not_be_owner
doc_default_role_can_not_be_owner
Error message
Doc default role can not be owner.
What it means
updateDocDefaultRole refuses role === DocRole.Owner. The default role is what every workspace member effectively gets on the doc; ownership must remain an explicit per-user grant, so making Owner the doc default is rejected with DocDefaultRoleCanNotBeOwner.
Solutions
- Choose Admin (or lower) as the default role and filter Owner out of the default-role options
- To grant ownership, use grantDocUserRoles for specific users instead of the default role
Example fix
// before
const allRoles = Object.values(DocRole); // includes Owner
await updateDocDefaultRole({ workspaceId, docId, role: 'Owner' }); // -> DOC_DEFAULT_ROLE_CAN_NOT_BE_OWNER
// after
const defaultRoleOptions = Object.values(DocRole).filter(r => r !== 'Owner');
await updateDocDefaultRole({ workspaceId, docId, role: 'Admin' }); Defensive patterns
Strategy: validation
Validate before calling
// Filter Owner out of default-role options before the call
const DEFAULT_ROLE_BLACKLIST = ['Owner'];
function isValidDefaultRole(role: DocRole): boolean {
return !DEFAULT_ROLE_BLACKLIST.includes(role);
}
if (!isValidDefaultRole(input.role)) {
throw new Error('default role cannot be Owner');
}
await updateDocDefaultRole(input); Type guard
function isDefaultRoleOwnerError(e: unknown): boolean {
return (
typeof e === 'object' && e !== null &&
(e as { extensions?: { code?: string } }).extensions?.code === 'doc_default_role_can_not_be_owner'
);
} Try / catch
try {
await updateDocDefaultRole(input);
} catch (e) {
if (isDefaultRoleOwnerError(e)) {
input.role = 'Admin'; // nearest valid default; Owner stays a per-user grant
await updateDocDefaultRole(input);
} else throw e;
} Prevention
- Generate the default-role dropdown from DocRole minus Owner
- Keep per-user role assignment (grantDocUserRoles) as the only way to convey ownership
- Validate roles against a whitelist at the form layer, not only server-side
When it happens
Trigger: Calling updateDocDefaultRole with input.role 'Owner' — typically a UI whose role dropdown lists every DocRole value including Owner, or code copying a member's Owner grant into the default-role field.
Common situations: Role pickers generated straight from the DocRole enum; settings forms that reuse the per-user role list for the default role.
Related errors
- expect_to_grant_doc_user_roles
- expect_to_revoke_doc_user_roles
- expect_to_update_doc_user_role
- expect_to_publish_doc
- expect_to_revoke_public_doc
AI-assisted analysis of toeverything/AFFiNE@2af30773ae (2026-08-18).
Data as JSON: /api/errors/084a06c771b91025.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/core/workspaces/resolvers/doc.ts:914
workspaceId: input.workspaceId,
docId: input.docId,
});
this.logger.log(`Update doc user role (${JSON.stringify(info)})`);
}
return true;
}
@Mutation(() => Boolean)
async updateDocDefaultRole(
@CurrentUser() user: CurrentUser,
@Args('input') input: UpdateDocDefaultRoleInput
) {
if (input.role === DocRole.Owner) {
this.logger.debug(
`Doc default role can not be owner (${JSON.stringify(input)})`
);
throw new DocDefaultRoleCanNotBeOwner();
}
const pairs = {
spaceId: input.workspaceId,
docId: input.docId,
};
if (input.workspaceId === input.docId) {
this.logger.error(
'Expect to update page default role, but it is a workspace',
pairs
);
throw new ExpectToUpdateDocUserRole(
pairs,
'Expect doc not to be workspace'
);
}
const newRole =
input.role === DocRole.None ? 'none' : toDomainDocRole(input.role);
if (!newRole) {View on GitHub (pinned to 2af30773ae)