#3639·teable

Deleting a lookup over a many-to-many link drops the link's shared junction table (record inserts then 500)

Author: ceejjaayy1Created Sep 3, 2026Updated Sep 7, 2026

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

  1. Table A has a many-to-many link field Employee to table B (symmetric field on B). Both tables have real linked rows.
  2. Table C has a link to table A (Products, many-to-one or one-to-many; it does not matter).
  3. On table C create a lookup field via the API: POST /api/table/{tableC}/field with {"type":"link","isLookup":true,"lookupOptions":{"foreignTableId":"<tableA>","linkFieldId":"<C.Products>","lookupFieldId":"<A.Employee>"}} (the created lookup's options are a copy of A.Employee's link options, including fkHostTableName).
  4. Delete that lookup field: DELETE /api/table/{tableC}/field/{lookupFieldId}.
  5. Insert any record into table A (POST /api/table/{tableA}/record) → 500 with the error above. SELECT on 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) shows options identical to the source link field, including fkHostTableName, 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_dump before any field work.