Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[FIX] Revert djangorestframework 3.15.2 → 3.14.0 to avoid UniqueTogetherValidator errors#2098

Merged
ritwik-g merged 1 commit into
mainZipstack/unstract:mainfrom
fix/revert-drf-bumpZipstack/unstract:fix/revert-drf-bumpCopy head branch name to clipboard
Jun 21, 2026
Merged

[FIX] Revert djangorestframework 3.15.2 → 3.14.0 to avoid UniqueTogetherValidator errors#2098
ritwik-g merged 1 commit into
mainZipstack/unstract:mainfrom
fix/revert-drf-bumpZipstack/unstract:fix/revert-drf-bumpCopy head branch name to clipboard

Conversation

@chandrasekharan-zipstack

Copy link
Copy Markdown
Contributor

What

Pins djangorestframework back to 3.14.0 (from 3.15.2, bumped in #2087). Reverts only the DRF entry; other batched bumps from #2087 are untouched. Touches both pyproject.toml + both uv.lock (root + backend). uv lock --check passes.

Why

DRF 3.15.2 regressed rc.343. DRF 3.15 auto-derives multi-field UniqueTogetherValidators from model UniqueConstraints (3.14 only did this for legacy unique_together). Every ModelSerializer(fields="__all__") over a model using Meta.constraints=[UniqueConstraint(...)] breaks two ways:

  1. Server-set constraint field (e.g. organization) → <field>: This field is required on create. Partially patched by [FIX] Mark server-managed organization field non-editable (DRF 3.15 compat) #2092 (5 org-attached models + mixin).
  2. Client-supplied constraint fields (TableSettings, ProfileManager, agentic table settings, lookups) → non_field_errors: "...must make a unique set" raised at is_valid(), short-circuiting the views' intended except IntegrityError: raise DuplicateData(<friendly>) path. This replaced the friendly message and moved the error from a top-level detail string into nested non_field_errors, which the frontend doesn't surface → silent failures.

QA-reported symptoms traced to this (rc.343)

  • Prompt table settings not editable after first save (re-save → 400, update_or_create never runs).
  • Duplicate LLM profile name → no error notification (silent fail); spec test_profile_manager_dependency: Expected duplicate-profile error, got "".

Trade-off

Loses the CVE-2024-21520 XSS patch carried by 3.15.2 — intentionally deprioritized for now. The 3.15 upgrade will be reattempted as its own PR with a serializer-level fix (drop auto-derived uniqueness validators so duplicates flow to the DB IntegrityError → DuplicateData path).

Note on recent fixes

The organization editable=False changes (#2092) remain correct under 3.14 — org is set server-side in save() from UserContext, never from request input, and the migrations are state-only (no DDL). No rollback needed there.

🤖 Generated with Claude Code

The DRF 3.15.2 bump (#2087) regressed rc.343. DRF 3.15 auto-derives
multi-field UniqueTogetherValidators from model UniqueConstraints, which
3.14 only did for legacy unique_together. Two breakages followed for every
ModelSerializer(fields="__all__") over a model using Meta.constraints:

1. Server-set constraint fields (e.g. organization) -> "<field>: required"
   on create. Partially patched by #2092 for the 5 org-attached models.
2. Client-supplied constraint fields (TableSettings, ProfileManager,
   agentic table settings, lookups) -> "...must make a unique set" raised at
   is_valid(), short-circuiting the views' intended
   `except IntegrityError: raise DuplicateData(<friendly>)` path. This both
   replaced the friendly message and moved the error from a top-level
   `detail` string into nested `non_field_errors`, which the frontend does
   not surface -> silent failures (e.g. duplicate LLM profile name, table
   settings no longer editable after first save).

Pin back to 3.14.0 to restore the known-good behaviour across the whole
unique-constraint class at once. The CVE-2024-21520 XSS patch carried by
3.15.2 is intentionally deprioritized; the 3.15 upgrade will be reattempted
later with a serializer-level fix (drop auto-derived uniqueness validators).

Reverts only the DRF entry from #2087; other batched bumps untouched. The
org `editable=False` changes (#2092) remain correct no-ops under 3.14 (org
is set server-side in save() from UserContext), so no rollback is needed there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8hAHc4HUo42zY1g9LAjKu
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Two pyproject.toml files downgrade the pinned djangorestframework version from 3.15.2 to 3.14.0: one in backend/pyproject.toml under the main project dependencies, and one in the root pyproject.toml under the hook-check-django-migrations dev dependency group.

Changes

DRF Version Pin Downgrade

Layer / File(s) Summary
djangorestframework pinned to 3.14.0
backend/pyproject.toml, pyproject.toml
Both files change the djangorestframework pin from 3.15.2 to 3.14.0 — one in the main backend dependencies list and one in the hook-check-django-migrations dependency group.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description covers all critical template sections: What (dependency revert details), Why (detailed explanation of DRF 3.15 regressions with specific failure modes), How (pinning approach), breaking changes assessment, dependencies versions, and related issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and specifically identifies the main change: reverting djangorestframework to a previous version to fix UniqueTogetherValidator errors.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/revert-drf-bump

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.

@greptile-apps

greptile-apps Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reverts djangorestframework from 3.15.2 back to 3.14.0 to unblock staging, where 3.15's new auto-derivation of UniqueTogetherValidator from Meta.constraints=[UniqueConstraint(...)] caused silent failures on several create/update flows. All four affected files (backend/pyproject.toml, backend/uv.lock, pyproject.toml, uv.lock) are updated consistently.

  • Version pinned to ==3.14.0 in both pyproject.toml files; lock files updated with correct hashes, URLs, and pytz re-added as a transitive dependency (dropped by DRF 3.15.x, required by 3.14.x).
  • The PR explicitly acknowledges that the CVE-2024-21520 XSS fix carried by 3.15.2 is intentionally sacrificed for now, with a follow-up upgrade planned.

Confidence Score: 4/5

Safe to merge as a hotfix; the revert is surgical and all four files are consistent with each other.

The change is mechanically correct — version pins match across both pyproject.toml files, lock file hashes are updated to real PyPI artifacts, and pytz is correctly re-introduced as a transitive dependency for DRF 3.14.0. The one open item is that reverting knowingly re-exposes CVE-2024-21520 (XSS in the browsable API); the team has explicitly accepted this trade-off and plans a follow-up PR, but until that lands the vulnerability window is open.

No file changes need attention beyond the acknowledged CVE trade-off; the lock files and pyproject.toml entries are fully consistent.

Security Review

  • CVE-2024-21520 (XSS, DRF browsable API): Reverting to DRF 3.14.0 re-exposes a known reflected XSS vulnerability in the browsable API renderer. The PR description explicitly acknowledges this as a deliberate, time-limited trade-off, with a follow-up upgrade planned. Actual risk depends on whether BrowsableAPIRenderer is disabled in production environments.

Important Files Changed

Filename Overview
backend/pyproject.toml Pins djangorestframework from 3.15.2 to 3.14.0; single-line, consistent with lock file update
backend/uv.lock Lock file correctly updated: package entry, hashes, URLs, and pytz re-added as a transitive dependency for DRF 3.14.0
pyproject.toml Root pyproject.toml version pin updated consistently with backend/pyproject.toml
uv.lock Root lock file updated with correct DRF 3.14.0 hashes and pytz dependency; matches backend/uv.lock changes

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["DRF 3.15.2 (was pinned)"] -->|"auto-derives UniqueTogetherValidator\nfrom Meta.constraints=[UniqueConstraint(...)]"| B["ModelSerializer is_valid()"]
    B -->|"constraint field server-set (e.g. org)"| C["400: field required on create"]
    B -->|"constraint fields client-supplied"| D["400: non_field_errors unique-set\nshort-circuits IntegrityError path"]
    D --> E["Silent failure — friendly DuplicateData\nnever raised; frontend sees nothing"]

    F["DRF 3.14.0 (this PR)"] -->|"no auto-derivation from UniqueConstraint"| G["ModelSerializer is_valid() passes"]
    G --> H["DB IntegrityError on duplicate"]
    H --> I["except IntegrityError → DuplicateData\nfriendly message surfaced to frontend"]

    style A fill:#f88,stroke:#c00
    style F fill:#8f8,stroke:#080
    style E fill:#f88,stroke:#c00
    style I fill:#8f8,stroke:#080
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["DRF 3.15.2 (was pinned)"] -->|"auto-derives UniqueTogetherValidator\nfrom Meta.constraints=[UniqueConstraint(...)]"| B["ModelSerializer is_valid()"]
    B -->|"constraint field server-set (e.g. org)"| C["400: field required on create"]
    B -->|"constraint fields client-supplied"| D["400: non_field_errors unique-set\nshort-circuits IntegrityError path"]
    D --> E["Silent failure — friendly DuplicateData\nnever raised; frontend sees nothing"]

    F["DRF 3.14.0 (this PR)"] -->|"no auto-derivation from UniqueConstraint"| G["ModelSerializer is_valid() passes"]
    G --> H["DB IntegrityError on duplicate"]
    H --> I["except IntegrityError → DuplicateData\nfriendly message surfaced to frontend"]

    style A fill:#f88,stroke:#c00
    style F fill:#8f8,stroke:#080
    style E fill:#f88,stroke:#c00
    style I fill:#8f8,stroke:#080
Loading

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
backend/pyproject.toml:22
**Known XSS exposure from CVE-2024-21520**

DRF 3.14.0 is vulnerable to CVE-2024-21520 (a reflected XSS in the browsable API). The PR description acknowledges this deliberately. Worth tracking an explicit issue/ticket for the follow-up upgrade so the window doesn't widen — the browsable API is typically disabled in production (`DEFAULT_RENDERER_CLASSES` without `BrowsableAPIRenderer`), which substantially reduces the actual attack surface, but it's worth confirming that setting is enforced in all deployed environments.

Reviews (1): Last reviewed commit: "[FIX] Revert djangorestframework 3.15.2 ..." | Re-trigger Greptile

Comment thread backend/pyproject.toml
@chandrasekharan-zipstack chandrasekharan-zipstack changed the title [FIX] Revert djangorestframework 3.15.2 → 3.14.0 to unblock staging [FIX] Revert djangorestframework 3.15.2 → 3.14.0 to avoid UniqueTogetherValidator errors Jun 20, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/pyproject.toml`:
- Line 22: The djangorestframework dependency is pinned to version 3.14.0, which
contains CVE-2024-21520, a known XSS vulnerability in the Browsable API's header
handling. Update the version constraint for djangorestframework in the
dependencies to 3.15.2 or later to resolve this vulnerability. If upgrading is
not immediately possible due to runtime constraints, document the security risk
with a clear explanation and establish a time-bound follow-up task to complete
the upgrade.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1b1c0f69-3162-4203-8f00-015af05921f0

📥 Commits

Reviewing files that changed from the base of the PR and between de49f06 and 53016e0.

⛔ Files ignored due to path filters (2)
  • backend/uv.lock is excluded by !**/*.lock
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • backend/pyproject.toml
  • pyproject.toml

Comment thread backend/pyproject.toml
@github-actions

Copy link
Copy Markdown
Contributor

Unstract test results

Per-group results

Status Group Tier Passed Failed Errors Skipped Duration (s)
unit-connectors unit 64 12 0 3 16.8
unit-core unit 0 0 4 0 1.2
unit-platform-service unit 9 0 1 0 1.4
unit-prompt-service unit 15 0 0 0 20.5
unit-rig unit 53 0 0 0 3.4
unit-runner unit 11 0 0 0 3.1
unit-sdk1 unit 390 0 0 0 20.7
unit-tool-registry unit 0 0 1 0 1.3
unit-workers unit 0 0 0 0 17.8
TOTAL 542 12 6 3 86.1

Critical paths

⚠️ Critical paths not yet covered

  • auth-login — User can log in and obtain a session cookie. (entry: POST /api/v1/auth/login; declared coverage: no groups declared)
  • adapter-register-llm — Register and validate an LLM adapter. (entry: POST /api/v1/adapter/; declared coverage: no groups declared)
  • workflow-create-execute — Create a workflow, configure source+destination, execute, poll, fetch result. (entry: POST /api/v1/workflow/{id}/execute/; declared coverage: e2e-workflow)
  • api-deployment-run — Deploy a workflow as an API, POST a document, receive structured JSON. (entry: POST /deployment/api/{org}/{name}/; declared coverage: e2e-api-deployment)
  • prompt-studio-fetch-response — Prompt Studio: create project, add prompt, run single-pass, get response. (entry: POST /api/v1/prompt-studio/prompt-studio-tool/{id}/fetch_response/; declared coverage: e2e-prompt-studio)
  • pipeline-etl-execute — Run an ETL pipeline from source connector to destination. (entry: POST /api/v1/pipeline/{id}/execute/; declared coverage: no groups declared)
  • usage-token-tracking — Per-execution token usage is recorded and retrievable. (entry: GET /api/v1/usage/get_token_usage/; declared coverage: no groups declared)
  • workflow-execution-fan-out — Multi-file workflow execution fans out to file-processing workers and rejoins. (entry: internal: backend → rabbitmq → workers/file_processing; declared coverage: no groups declared)
  • callback-result-delivery — Async results are posted back via the callback worker. (entry: internal: workers/callback → backend /internal endpoints; declared coverage: no groups declared)
✅ Covered critical paths
  • tool-sandbox-exec — covered by unit-runner

@ritwik-g ritwik-g merged commit 7aba21f into main Jun 21, 2026
9 checks passed
@ritwik-g ritwik-g deleted the fix/revert-drf-bump branch June 21, 2026 05:18
@sonarqubecloud

Copy link
Copy Markdown

chandrasekharan-zipstack added a commit that referenced this pull request Jun 24, 2026
* [FIX] Re-bump djangorestframework 3.14.0 -> 3.17.1

Re-attempts the DRF upgrade reverted in #2098. 3.17.1 is chosen because it:
- carries PR encode/django-rest-framework#9766 (3.17.0), so the auto
  UniqueTogetherValidator honors a UniqueConstraint's violation_error_message
  for friendly duplicate messages (used by cloud-side create-only serializers),
- includes the CVE-2024-21520 (XSS) fix first shipped in 3.15.2.

Safe to layer on top of the Meta.validators=[] changes in the parent commit,
which neutralize the 3.15+ auto-validator for every upsert / IntegrityError-catch
serializer. Django 4.2.30 + Python 3.12 satisfy DRF 3.17's floors.

MUST be build + test + staging validated before merge (this bump caused the
rc.343 regression). drf-yasg 1.21.7 / drf-standardized-errors compatibility with
DRF 3.17 to be verified in CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8hAHc4HUo42zY1g9LAjKu

* [FIX] Remove unused hook-check-django-migrations dep group

Group had no consumer (migration check runs in backend env); its pinned
drf-yasg==1.21.7 paired with DRF 3.17.1 in the root lock was an incompatible
skew. Drop the group and relock.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8hAHc4HUo42zY1g9LAjKu

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
chandrasekharan-zipstack added a commit that referenced this pull request Jun 24, 2026
…auto UniqueTogetherValidator on upsert/catch serializers (#2104)

* [FIX] Drop DRF auto UniqueTogetherValidator on upsert/catch serializers

DRF 3.15+ auto-generates a UniqueTogetherValidator from each model's
Meta.constraints UniqueConstraint. For serializers whose view already owns
uniqueness (upsert via update_or_create, or IntegrityError->Duplicate catch),
that validator fires at is_valid() and 400s on a legitimate re-save before the
view can run, short-circuiting the view's duplicate handling.

Set Meta.validators = [] on those serializers so the view/DB own uniqueness.
No-op on the currently-pinned DRF 3.14 (which only auto-validates legacy
unique_together); required once DRF is re-bumped to 3.17.x.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8hAHc4HUo42zY1g9LAjKu

* [FIX] Re-bump djangorestframework 3.14.0 → 3.17.1 (#2105)

* [FIX] Re-bump djangorestframework 3.14.0 -> 3.17.1

Re-attempts the DRF upgrade reverted in #2098. 3.17.1 is chosen because it:
- carries PR encode/django-rest-framework#9766 (3.17.0), so the auto
  UniqueTogetherValidator honors a UniqueConstraint's violation_error_message
  for friendly duplicate messages (used by cloud-side create-only serializers),
- includes the CVE-2024-21520 (XSS) fix first shipped in 3.15.2.

Safe to layer on top of the Meta.validators=[] changes in the parent commit,
which neutralize the 3.15+ auto-validator for every upsert / IntegrityError-catch
serializer. Django 4.2.30 + Python 3.12 satisfy DRF 3.17's floors.

MUST be build + test + staging validated before merge (this bump caused the
rc.343 regression). drf-yasg 1.21.7 / drf-standardized-errors compatibility with
DRF 3.17 to be verified in CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8hAHc4HUo42zY1g9LAjKu

* [FIX] Remove unused hook-check-django-migrations dep group

Group had no consumer (migration check runs in backend env); its pinned
drf-yasg==1.21.7 paired with DRF 3.17.1 in the root lock was an incompatible
skew. Drop the group and relock.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G8hAHc4HUo42zY1g9LAjKu

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.