[FIX] Revert djangorestframework 3.15.2 → 3.14.0 to avoid UniqueTogetherValidator errors#2098
Conversation
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
WalkthroughTwo ChangesDRF Version Pin Downgrade
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~2 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
| 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
%%{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
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
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (2)
backend/uv.lockis excluded by!**/*.lockuv.lockis excluded by!**/*.lock
📒 Files selected for processing (2)
backend/pyproject.tomlpyproject.toml
Unstract test resultsPer-group results
Critical paths
|
|
* [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>
…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>
What
Pins
djangorestframeworkback to 3.14.0 (from 3.15.2, bumped in #2087). Reverts only the DRF entry; other batched bumps from #2087 are untouched. Touches bothpyproject.toml+ bothuv.lock(root + backend).uv lock --checkpasses.Why
DRF 3.15.2 regressed rc.343. DRF 3.15 auto-derives multi-field
UniqueTogetherValidators from modelUniqueConstraints (3.14 only did this for legacyunique_together). EveryModelSerializer(fields="__all__")over a model usingMeta.constraints=[UniqueConstraint(...)]breaks two ways:organization) →<field>: This field is requiredon create. Partially patched by [FIX] Mark server-managed organization field non-editable (DRF 3.15 compat) #2092 (5 org-attached models + mixin).non_field_errors: "...must make a unique set"raised atis_valid(), short-circuiting the views' intendedexcept IntegrityError: raise DuplicateData(<friendly>)path. This replaced the friendly message and moved the error from a top-leveldetailstring into nestednon_field_errors, which the frontend doesn't surface → silent failures.QA-reported symptoms traced to this (rc.343)
update_or_createnever runs).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 → DuplicateDatapath).Note on recent fixes
The
organization editable=Falsechanges (#2092) remain correct under 3.14 — org is set server-side insave()fromUserContext, never from request input, and the migrations are state-only (no DDL). No rollback needed there.🤖 Generated with Claude Code