Deleting a lookup over a many-to-many link drops the link's shared junction table (record inserts then 500)
Describe the bug Deleting a lookup field whose source is a many-to-many link drops the shared junction table that the original link field (and its symmetric field) still reference. After the delete, every record insert on the table that owns the link fails with HTTP 500:
PrismaClientKnownRequestError: Invalid `prisma.$queryRawUnsafe()` invocation:
Raw query failed. Code: `42P01`. Message: `relation "<baseSchema>.junction_<symField>_<linkField>" does not exist`Both live link fields' options still carry fkHostTableName = <baseSchema>.junction_<symField>_<linkField>, but the relation is gone from PostgreSQL.
To Reproduce
- Table A has a many-to-many link field
Employeeto table B (symmetric field on B). Both tables have real linked rows. - Table C has a link to table A (
Products, many-to-one or one-to-many; it does not matter). - On table C create a lookup field via the API:
POST /api/table/{tableC}/fieldwith{"type":"link","isLookup":true,"lookupOptions":{"foreignTableId":"<tableA>","linkFieldId":"<C.Products>","lookupFieldId":"<A.Employee>"}}(the created lookup'soptionsare a copy of A.Employee's link options, includingfkHostTableName). - Delete that lookup field:
DELETE /api/table/{tableC}/field/{lookupFieldId}. - Insert any record into table A (
POST /api/table/{tableA}/record) → 500 with the error above.SELECTon the junction relation confirms it was dropped.
We hit this twice in one day (once from a scripted create+delete of the lookup, once from an aborted field conversion that deleted its newly created lookup on rollback). Recovery required restoring the junction table from a pg_dump.
Expected behavior Deleting a lookup field must never drop storage owned by the link field it looks up. Only deleting the last of the link/symmetric pair should drop the junction.
Screenshots N/A (API reproduction).
** Client (please complete the following information):**
- OS: macOS (API calls via curl/python)
- Browser: n/a
- Version: n/a
Platform (Please tell us which deployment version you are using)
docker-standalone (Community Edition), image ghcr.io/teableio/teable:release.2026-08-09T14-50-08Z.2564, PostgreSQL 15.4, Redis 7.2.4.
Additional context
- The lookup field row in
public.field(after soft delete) showsoptionsidentical to the source link field, includingfkHostTableName,selfKeyName,foreignKeyName,symmetricFieldId— which suggests the delete path treats the lookup as owning the junction. - Workaround we adopted: never create or delete lookups over many-to-many links on this build; keep a fresh
pg_dumpbefore any field work.
Source: teableio/teable