toeverything/AFFiNE · error · ActionForbidden
action_forbidden
action_forbidden
Error message
This feature is temporarily unavailable for you.
What it means
publishDoc runs assertCanShare before publishing. If the acting user is currently quarantined or banned by the invite-abuse system, the action is refused with ActionForbidden and a deliberately generic message. This is an anti-abuse gate, not a permissions bug: the user may hold Doc.Publish on the workspace and still be blocked from share actions.
Solutions
- Appeal the flag or contact support to have the quarantine lifted for the account
- If the quarantine is time-based, wait for it to expire and retry
- Publish from a different, unflagged account that has Doc.Publish rights on the workspace
Defensive patterns
Strategy: try-catch
Type guard
function isActionForbidden(e: unknown): boolean {
return (
typeof e === 'object' && e !== null &&
(e as { extensions?: { code?: string } }).extensions?.code === 'action_forbidden'
);
} Try / catch
try {
await publishDoc(wsId, docId, mode);
} catch (e) {
if (isActionForbidden(e)) {
showRestrictedMessage('Sharing is temporarily unavailable for this account.'); // do not retry
} else throw e;
} Prevention
- Treat action_forbidden on share actions as a terminal state for that user — do not auto-retry
- Surface the generic message to users; the specifics live in server logs only
- Keep invite/share automation within normal volumes to avoid tripping abuse heuristics
When it happens
Trigger: A publishDoc mutation executed by an account flagged by the invite-abuse heuristics (mass invites, spam-like behavior). The server logs 'Share action blocked for quarantined actor' with the userId and context.
Common situations: Cloud-hosted AFFiNE accounts that tripped abuse detection; automation/scripts issuing many invite or share operations that resemble spam.
Related errors
- action_forbidden
- action_forbidden_on_non_team_workspace
- can_not_revoke_yourself
- expect_to_publish_doc
- expect_to_revoke_public_doc
AI-assisted analysis of toeverything/AFFiNE@2af30773ae (2026-08-18).
Data as JSON: /api/errors/c9f1517e7f167e24.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/core/workspaces/resolvers/doc.ts:332
private readonly ac: PermissionAccess,
private readonly models: Models,
private readonly cache: Cache,
private readonly event: EventBus,
private readonly runtime: BackendRuntimeProvider
) {}
@ResolveField(() => WorkspaceDocMeta, {
description: 'Cloud page metadata of workspace',
complexity: 2,
deprecationReason: 'use [WorkspaceType.doc] instead',
})
async pageMeta(
@CurrentUser() me: CurrentUser,
@Parent() workspace: WorkspaceType,
@Args('pageId') pageId: string
) {
await this.ac.user(me.id).doc(workspace.id, pageId).assert('Doc.Read');
const metadata = await this.models.doc.getAuthors(workspace.id, pageId);
if (!metadata) {
throw new DocNotFound({ spaceId: workspace.id, docId: pageId });
}
return {
createdAt: metadata.createdAt,
updatedAt: metadata.updatedAt,
createdBy: metadata.createdByUser || null,
updatedBy: metadata.updatedByUser || null,
};
}
@ResolveField(() => [DocType], {
description: 'Get public docs of a workspace',
complexity: 2,
})
async publicDocs(@Parent() workspace: WorkspaceType) {View on GitHub (pinned to 2af30773ae)