Skip to content

fix: add ON DELETE CASCADE to span.trace_id foreign key#12384

Open
xr843 wants to merge 4 commits intolangflow-ai:mainfrom
xr843:fix/flow-deletion-fk-cascade
Open

fix: add ON DELETE CASCADE to span.trace_id foreign key#12384
xr843 wants to merge 4 commits intolangflow-ai:mainfrom
xr843:fix/flow-deletion-fk-cascade

Conversation

@xr843
Copy link
Copy Markdown

@xr843 xr843 commented Mar 29, 2026

Summary

  • Adds Alembic migration to drop and re-create the span.trace_id FK with ON DELETE CASCADE, completing the cascade chain flow → trace → span at the database level
  • Updates SpanTable model to include ondelete="CASCADE" on trace_id field so new deployments get the correct schema
  • Adds explicit DELETE for SpanTable and TraceTable in cascade_delete_flow() for defence in depth, matching the existing pattern for MessageTable, TransactionTable, VertexBuildTable, and FlowVersion

Fixes #12346

Details

The original migration 3478f0bd6ccb created the span.trace_id FK without ondelete="CASCADE". When PostgreSQL cascades a flow deletion through flow → trace (which correctly has CASCADE), it then tries to delete trace rows but fails because span rows still reference them without a cascade rule.

Changes

File Change
alembic/versions/83cd04b12a34_add_ondelete_cascade_to_span_trace_id_fk.py New migration: drops existing FK, re-creates with ON DELETE CASCADE
services/database/models/traces/model.py Added ondelete="CASCADE" to SpanTable.trace_id Field
api/utils/core.py Added explicit span/trace deletion in cascade_delete_flow()

Migration safety

  • Uses batch_alter_table for SQLite compatibility
  • Guards with table_exists check
  • Introspects actual FK constraint name (handles both auto-generated and named constraints)
  • Fully reversible downgrade() function
  • Follows the exact same pattern as existing cascade migrations (0e6138e7a0c2, 59a272d6669a)

Test plan

  • Run migration against PostgreSQL: alembic upgrade head
  • Run migration against SQLite: alembic upgrade head
  • Create a flow, execute it to generate traces/spans, then delete the flow — should succeed without ForeignKeyViolation
  • Run alembic downgrade -1 to verify reversibility
  • Verify existing flows without traces can still be deleted

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved data consistency by implementing cascade deletion for trace and span records to ensure proper cleanup and prevent orphaned data when flows are deleted.
  • Chores

    • Updated package dependencies for improved stability and compatibility.

Flow deletion fails with ForeignKeyViolation when traces exist because
the span.trace_id FK was created without ON DELETE CASCADE, breaking the
cascade chain flow -> trace -> span.

This commit:
- Adds an Alembic migration to drop and re-create the span.trace_id FK
  with ON DELETE CASCADE (database-level fix)
- Updates the SpanTable model to include ondelete="CASCADE" on trace_id
- Adds explicit delete of SpanTable and TraceTable in cascade_delete_flow
  for defence in depth (matches existing pattern for other child tables)

Fixes langflow-ai#12346

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@github-actions github-actions bot added the community Pull Request from an external contributor label Mar 29, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c4394ac5-05b5-43ef-ab1b-e9684d71f1a7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This pull request fixes a foreign key constraint violation that occurs when deleting flows with associated execution traces. The fix applies both database-level changes (adding ON DELETE CASCADE to the span.trace_id foreign key constraint via migration and ORM model update) and application-level changes (explicit deletion of spans and traces in the cascade_delete_flow function).

Changes

Cohort / File(s) Summary
Database Schema Migration
src/backend/base/langflow/alembic/versions/83cd04b12a34_add_ondelete_cascade_to_span_trace_id_fk.py
New Alembic migration that adds ON DELETE CASCADE to the span.trace_id foreign key constraint. Upgrade path checks for existing FK and recreates it with cascade behavior; downgrade path removes cascade configuration and lets the database auto-generate the constraint name.
Cascade Deletion Logic
src/backend/base/langflow/api/utils/core.py
Modified cascade_delete_flow function to explicitly delete SpanTable and TraceTable records before deleting parent Flow records, ensuring proper deletion order and preventing foreign key constraint violations.
ORM Model Configuration
src/backend/base/langflow/services/database/models/traces/model.py
Updated SpanTable.trace_id field definition to include ondelete="CASCADE" parameter in the Field() declaration, aligning ORM-level cascade configuration with the database-level constraint.
Dependency Updates
src/lfx/src/lfx/_assets/component_index.json
Updated google package dependency versions from 2.30.0 to 2.8.0 across multiple component entries; updated corresponding SHA256 checksum.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 4 warnings)

Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error PR modifies critical database cascade logic but includes no automated test files for migration execution, cascade_delete_flow behavior, or foreign key cascade validation. Add test files: migration test (test_migration_83cd04b12a34.py) and cascade_delete_flow tests verifying proper deletion of traces/spans and no ForeignKeyViolation errors on both database backends.
Out of Scope Changes check ⚠️ Warning The PR includes an out-of-scope change: component_index.json was updated with Google package version downgrade (2.30.0 to 2.8.0) and SHA256 hash, which is unrelated to the span.trace_id cascade deletion fix. Remove the component_index.json changes from this PR as they are unrelated to the cascade deletion fix, or address them in a separate PR with appropriate context.
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Quality And Coverage ⚠️ Warning PR lacks test coverage for application-level cascade_delete_flow() changes and end-to-end flow deletion with trace/span data. Add tests for cascade_delete_flow() function with trace/span data and end-to-end test of flow deletion API with actual cascade delete chain.
Test File Naming And Structure ⚠️ Warning No test files were added to verify the cascade deletion functionality or Alembic migration changes. Add test files following pytest naming conventions to verify cascade_delete_flow function and migration upgrade/downgrade functionality.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding ON DELETE CASCADE to the span.trace_id foreign key to fix a ForeignKeyViolation bug, which is the primary objective of this PR.
Linked Issues check ✅ Passed All coding objectives from issue #12346 are met: the migration alters the span.trace_id FK with ON DELETE CASCADE for database-level robustness, the SpanTable model is updated with ondelete="CASCADE", and cascade_delete_flow explicitly deletes SpanTable and TraceTable for application-level safety.
Excessive Mock Usage Warning ✅ Passed The PR does not include any test files, so mock usage cannot be assessed.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the bug Something isn't working label Mar 29, 2026
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Mar 29, 2026
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Mar 29, 2026
@github-actions github-actions bot added bug Something isn't working and removed bug Something isn't working labels Mar 30, 2026
@xr843
Copy link
Copy Markdown
Author

xr843 commented Mar 30, 2026

CI Failure Analysis

All three CI failures are unrelated to this PR's changes:

1. Ruff Style Check (PERF403) — setup.py:68

Pre-existing issue on main. The failing file (src/backend/base/langflow/initial_setup/setup.py) is not modified by this PR. The same Ruff Style Check workflow also fails on main.

2. Test Docker Images — Node.js download failure

The Docker build fails during Node.js installation (npm install -g npm@latest exit code 1). This is an infrastructure/networking issue in the Docker build, unrelated to our database migration or Python code changes.

3. validate-migration — "Resource not accessible by integration"

This is a known GitHub Actions permissions limitation for fork PRs. The workflow actually validated the migration successfully (the log shows ✅ Migration Validation Passed — All migrations follow the Expand-Contract pattern correctly), but it cannot post the status comment back to the PR due to restricted token permissions on fork PRs.

Passing checks relevant to this PR

  • Mypy (3.10, 3.11, 3.12, 3.13) — all pass
  • Run Ruff Check and Format — passes (separate from Ruff Style Check)
  • Backend Unit Tests & Integration Tests
  • Frontend Tests
  • Update Component Index / Starter Projects

@xr843
Copy link
Copy Markdown
Author

xr843 commented Mar 30, 2026

Hi maintainers, the Ruff Style Check failure is not related to this PR.

The error is a pre-existing PERF403 violation in src/backend/base/langflow/initial_setup/setup.py:68, which is not a file modified by this PR. The same violation exists on the main branch.

Happy to rebase once this is resolved upstream!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working community Pull Request from an external contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flow deletion fails with ForeignKeyViolation when traces exist — span.trace_id FK missing ON DELETE CASCADE

1 participant