toeverything/AFFiNE · error · DocIsNotPublic
doc_is_not_public
doc_is_not_public
Error message
Doc is not public.
What it means
DocIsNotPublic, thrown by DocModel.unpublish() (doc.ts:590-601). unpublish is a guarded state transition: it first awaits isPublic(workspaceId, docId) (which reads the doc meta's public flag) and throws when the doc was never published or is already unpublished, before upserting meta with public: false and publishedAt: null.
Solutions
- Check the published state first (isPublic) and skip the call when not public - make unpublish idempotent at the call site
- Catch DocIsNotPublic and treat it as success when you only need the end state 'not published'
- Refresh the doc's public state in the UI when the badge disagrees with the server
Example fix
// before
await doc.unpublish(workspaceId, docId);
// after - idempotent unpublish
if (await doc.isPublic(workspaceId, docId)) {
await doc.unpublish(workspaceId, docId);
} Defensive patterns
Strategy: validation
Validate before calling
if (await doc.isPublic(workspaceId, docId)) {
await doc.unpublish(workspaceId, docId);
} Try / catch
try {
await doc.unpublish(workspaceId, docId);
} catch (e) {
if (e instanceof DocIsNotPublic) return; // already unpublished - treat as success
throw e;
} Prevention
- Make unpublish idempotent at the call site with an isPublic pre-check
- Refresh publish state after actions that change it
- Guard double-clicks and network retries in the UI
When it happens
Trigger: unpublish(workspaceId, docId) on a doc whose meta does not have public = true - never published, already unpublished (double call), or no meta row yet.
Common situations: Retried unpublish requests (double-click, network retry); UI showing a stale 'Published' badge; cleanup routines unpublishing every doc indiscriminately.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of toeverything/AFFiNE@2af30773ae (2026-08-18).
Data as JSON: /api/errors/f0ccc1d2c826f5df.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/models/doc.ts:609
/**
* Publish a doc as public.
*/
async publish(
workspaceId: string,
docId: string,
mode: PublicDocMode = PublicDocMode.Page
) {
return await this.upsertMeta(workspaceId, docId, {
public: true,
mode,
publishedAt: new Date(),
});
}
@Transactional()
async unpublish(workspaceId: string, docId: string) {
if (!(await this.isPublic(workspaceId, docId))) {
throw new DocIsNotPublic();
}
return await this.upsertMeta(workspaceId, docId, {
public: false,
publishedAt: null,
});
}
/**
* Check if the doc is public.
*/
async isPublic(workspaceId: string, docId: string) {
const policy = await this.db.docAccessPolicy.findUnique({
where: { workspaceId_docId: { workspaceId, docId } },
select: { visibility: true, publicRole: true },
});
return policy?.visibility === 'public' && policy.publicRole === 'external';
}View on GitHub (pinned to 2af30773ae)