Skip to content

Deleting a flow with existing trace/span records fails on PostgreSQL because span.trace_id is not ON DELETE CASCADE #12732

@ltotal0925

Description

@ltotal0925

Bug Description

When using Langflow with PostgreSQL, deleting a flow can fail if that flow already has tracing data (trace and span rows).

The flow runs normally, and tracing data is created normally. The problem happens later when deleting the flow from the UI.

The underlying issue appears to be that:

  • trace.flow_id -> flow.id uses ON DELETE CASCADE
  • but span.trace_id -> trace.id does not use ON DELETE CASCADE

Because of that, deleting a flow cascades into trace, but the referenced span rows still block deletion, causing a foreign key violation.

Observed error in logs:

psycopg.errors.ForeignKeyViolation: update or delete on table "trace" violates foreign key constraint "span_trace_id_fkey" on table "span"
DETAIL:  Key (id)=(...) is still referenced from table "span".

And then:

RuntimeError: ('Unable to cascade delete flow: ...', IntegrityError(...))

This was reproduced on langflowai/langflow:1.9.0. I had also seen the same behavior previously on 1.8.x.

Environment:

- Langflow 1.9.0
- PostgreSQL
- tracing data exists for the flow
- deleting flow from the Langflow UI

Additional context:

- This does not appear to be caused by stale local data or a one-off corrupted database.
- The issue is reproducible on a fresh PostgreSQL-backed Langflow setup after creating tracing data and then deleting the flow.
- In my case, fixing the DB constraint manually by changing span.trace_id -> trace.id to ON DELETE CASCADE makes flow deletion work again immediately.

### Reproduction

1. Start Langflow with PostgreSQL as the main database.
2. Create or import a flow.
3. Run the flow at least once so tracing data is written.
4. In the UI, delete that flow.

Result:
- deletion fails
- Langflow logs show `span_trace_id_fkey` blocking the delete

Optional DB verification:

```sql
SELECT conname, pg_get_constraintdef(c.oid) AS definition
FROM pg_constraint c
JOIN pg_class t ON c.conrelid = t.oid
WHERE t.relname = 'span' AND conname = 'span_trace_id_fkey';

Observed result:

FOREIGN KEY (trace_id) REFERENCES trace(id)

So if trace rows are deleted, span rows are left behind unless they are deleted manually first.

### Expected behavior

Deleting a flow should also delete its related tracing data cleanly when PostgreSQL is used.

If a flow is deleted:
- related `trace` rows should be deleted
- related `span` rows should also be deleted automatically
- the UI delete action should succeed without manual database repair

At minimum, the PostgreSQL schema should define `span.trace_id -> trace.id` with `ON DELETE CASCADE`, or Langflow should explicitly delete dependent `span` rows before deleting `trace`/`flow`.

### Who can help?

_No response_

### Operating System

macOS Tahoe 26.4.1 with OrbStack Docker

### Langflow Version

1.9.0

### Python Version

3.12

### Screenshot

_No response_

### Flow File

_No response_

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions