AppFlowy-IO / AppFlowy-IO/AppFlowy-SelfHost-Commercial
Re-publishing a page tree fails with `duplicate key value violates unique constraint "af_published_blob_ref_pkey"
- Lingua principale
- Go Template
- Stelle
- 6
- Fork
- 5
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
## Summary
On a self-hosted deployment, publishing a page tree succeeds the **first** time, but **every subsequent publish of any tree that contains an already-published file attachment fails**. The whole publish transaction is rolled back, so the page can never be re-published or published under a new parent.
The insert into `af_published_blob_ref` appears to be missing an `ON CONFLICT DO NOTHING` (or an upsert), unlike the insert into `af_published_collab` right before it in the same transaction, which is already idempotent ("Inserting or replacing ...").
## Environment
- AppFlowy Cloud (self-hosted commercial fork): **0.17.8** — image `appflowyinc/appflowy_cloud:latest`, reported by the server as `Using AppFlowy Cloud version:0.17.8, using self-hosted version`
- Deployed with the official `docker-compose.yml`
- Storage: MinIO (`APPFLOWY_S3_USE_MINIO=true`)
- Postgres: `pgvector/pgvector:pg16`
- Client: AppFlowy desktop (macOS), `client_version` reported as `0.13.0`
## Steps to reproduce
1. Create a page tree that contains a page with a **file attachment** (in my case a `.pdf`).
2. Publish the top-level page. → **Succeeds.** A row is written to `af_published_blob_ref`.
3. Unpublish it from the app (optional — makes no difference).
4. Publish that page again, or publish any other page whose subtree includes the page holding that attachment. → **Fails every time.**
## Expected behaviour
The publish succeeds and the existing blob reference is reused / updated.
## Actual behaviour
The server returns **HTTP 200** with this error envelope (133 bytes):
```json
{"code":1020,"message":"error returned from database: duplicate key value violates unique constraint \"af_published_blob_ref_pkey\""}
```
The whole transaction is rolled back — including the ~19 rows that had just been written to `af_published_collab` — so nothing is published.
Because the error is returned with HTTP 200 and an error code the desktop client does not recognise, the UI only shows a generic **"internal error"**, which makes this very hard to diagnose from the app alone.
## Evidence
Relevant constraint:
```
af_published_blob_ref_pkey UNIQUE (workspace_id, view_id, s3_key)
```
Server log for a failing request (`RUST_LOG=debug`), showing the flow stopping exactly at the blob-ref insert:
```
INFO publish | Rewrote document assets for view_id=, found 0 blob keys
INFO publish | Extracted 1 file references from document
DEBUG publish | Inserting or replacing [ ...19 view ids... ]
INFO publish | Deleted existing published collab record with publish names: [...]
DEBUG publish | Inserting published blob refs for workspace_id: , view_id: ,
keys: ["public///=.pdf"]
DEBUG sqlx | INSERT INTO af_published_collab ( … rows_affected = 19
DEBUG sqlx | INSERT INTO af_published_blob_ref ( … rows_affected = 0
```
Note that **no `ERROR`/`WARN` level line is logged at all** for this failure, even at `RUST_LOG=debug`; the error is only visible in the HTTP response body. I had to capture the HTTP response on the wire to find out what was actually failing.
The pre-existing row that causes the collision (written by the first, successful publish):
```
workspace_id |
view_id |
s3_key | public///=.pdf
created_at | first successful publish
```
Side effect worth noting: the object **is** copied to `public/...` in S3/MinIO on every failed attempt (S3 is not part of the transaction), so failed publishes leave the copied object behind while the DB is rolled back.
## Impact
- Any page tree containing a file attachment can only ever be published **once**.
- Unpublishing from the app does **not** clean up `af_published_blob_ref`, so there is no in-app way to recover.
- Workarounds: delete the offending row from `af_published_blob_ref` manually, or remove the attachment from the document. I confirmed that removing the attachment makes the publish succeed immediately (the same request then returns a 56-byte success envelope instead of the 133-byte error).
## Suggested fix
Make the `af_published_blob_ref` insert idempotent, matching the behaviour of the `af_published_collab` insert in the same transaction, e.g.:
```sql
INSERT INTO af_published_blob_ref (workspace_id, view_id, s3_key)
VALUES (...)
ON CONFLICT (workspace_id, view_id, s3_key) DO NOTHING
```
It would also help a lot if this failure were logged at `ERROR` level, and if the desktop client surfaced the server-provided message instead of a generic "internal error".
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Valutazione
Questa issue non è ancora stata valutata.