toeverything/AFFiNE · error · ExpectToRevokePublicDoc
expect_to_revoke_public_doc
expect_to_revoke_public_doc
Error message
Expect doc not to be workspace
What it means
Thrown by revokePublicDoc when workspaceId === docId. Same rationale as publishDoc: the workspace root cannot be 'unpublished', so the server refuses with ExpectToRevokePublicDoc (invalid_input) and logs at error level.
Source
Thrown at packages/backend/server/src/core/workspaces/resolvers/doc.ts:505
this.logger.log(
`Publish page ${docId} with mode ${mode} in workspace ${workspaceId}`
);
return doc;
}
@Mutation(() => DocType)
async revokePublicDoc(
@CurrentUser() user: CurrentUser,
@Args('workspaceId') workspaceId: string,
@Args('docId') docId: string
) {
if (workspaceId === docId) {
this.logger.error('Expect to revoke public doc, but it is a workspace', {
workspaceId,
docId,
});
throw new ExpectToRevokePublicDoc('Expect doc not to be workspace');
}
await this.ac.user(user.id).doc(workspaceId, docId).assert('Doc.Publish');
const doc = await this.models.doc.unpublish(workspaceId, docId);
this.event.emit('doc.public_state.changed', { workspaceId, docId });
this.logger.log(`Revoke public doc ${docId} in workspace ${workspaceId}`);
return doc;
}
private async tryFixDocOwner(workspaceId: string, docId: string) {
const allowed = await this.cache.setnx(
`fixingOwner:${workspaceId}:${docId}`,
1,
// TODO(@forehalo): we definitely need a timer helper
{ ttl: 1000 * 60 * 60 * 24 }View on GitHub (pinned to 26c515e050)
Solutions
- Pass the actual public child page id as docId, not the workspace id.
- Disable the revoke action client-side when docId === workspaceId.
- Fix the data source that presented the workspace root as a public doc.
Example fix
// before
await gql.revokePublicDoc({ workspaceId, docId: workspaceId });
// after
if (docId === workspaceId) return; // nothing to revoke
await gql.revokePublicDoc({ workspaceId, docId }); Defensive patterns
Strategy: validation
Validate before calling
// Never revoke on the workspace root
if (docId === workspaceId) {
throw new Error('Cannot revoke public state of the workspace root');
}
await gql.revokePublicDoc({ workspaceId, docId }); Type guard
function isExpectToRevokePublicDoc(e: unknown): boolean {
return (
typeof e === 'object' &&
e !== null &&
(e as any).extensions?.code === 'expect_to_revoke_public_doc'
);
} Try / catch
try {
await gql.revokePublicDoc({ workspaceId, docId });
} catch (e) {
if (isExpectToRevokePublicDoc(e)) {
reportBug('revokePublicDoc called with workspaceId as docId');
return;
}
throw e;
} Prevention
- Filter the workspace root out of the 'public docs' list shown for revoke.
- Assert docId !== workspaceId before invoking revokePublicDoc.
- Use distinct variables for the selected doc versus the owning workspace.
When it happens
Trigger: Calling revokePublicDoc with docId equal to workspaceId - attempting to revoke publication of the workspace root doc.
Common situations: UI bug offering a 'revoke public' action on the workspace root; reused id variable; client not filtering the workspace id out of revocable docs.
Related errors
- expect_to_publish_doc
- expect_to_grant_doc_user_roles
- bad_request
- email_token_not_found
- same_email_provided
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/5c813974b051f0f4.
Report an issue: GitHub.