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

[HOTFIX] Raise URLValidator max_length to 8192 for long S3 presigned URLs#2111

Merged
ritwik-g merged 1 commit into
v0.176.4-hotfixZipstack/unstract:v0.176.4-hotfixfrom
hotfix/presigned-url-max-lengthZipstack/unstract:hotfix/presigned-url-max-lengthCopy head branch name to clipboard
Jun 24, 2026
Merged

[HOTFIX] Raise URLValidator max_length to 8192 for long S3 presigned URLs#2111
ritwik-g merged 1 commit into
v0.176.4-hotfixZipstack/unstract:v0.176.4-hotfixfrom
hotfix/presigned-url-max-lengthZipstack/unstract:hotfix/presigned-url-max-lengthCopy head branch name to clipboard

Conversation

@Deepak-Kesavan

Copy link
Copy Markdown
Contributor

Hotfix (Scenario 2: OSS-only) — target OSS `v0.176.4` → release `v0.176.5`

Problem

API deployment requests with S3 pre-signed URLs fail validation with:
```json
{"code":"invalid","detail":"Enter a valid URL.","attr":"presigned_urls.0"}
```
Django 5.0+ caps `URLValidator` at 2048 characters. Pre-signed URLs signed with temporary/STS credentials carry a large `X-Amz-Security-Token` (~1.5 KB), pushing the URL past 2048 chars, so DRF's `URLField` rejects them before they're ever parsed. Confirmed live against prod: the same URL trimmed under 2048 passes validation; at 2094 chars it fails.

Fix

Raise the global `URLValidator.max_length` to 8192 in settings. Scheme/host validation is unchanged; only the arbitrary length ceiling is lifted. No-op on Django 4.2.x (attribute not checked there). No DB/migration impact — the URL is downloaded transiently and never persisted.

Files

  • `backend/backend/settings/base.py` (applies to all envs via `from base import *`)

Follow-up (per Hotfix Deployment Guide)

  • Merge this PR into `v0.176.4-hotfix`
  • Cut OSS GitHub release `v0.176.5` targeting `v0.176.4-hotfix` (do not mark latest unless it's current prod)
  • Enterprise `v0.170.1-hotfix` branch → RC build pinning Specific OSS version `v0.176.5`
  • Back-merge `v0.176.4-hotfix` → `main` after prod deploy

@ritwik-g ritwik-g merged commit 8b3243c into v0.176.4-hotfix Jun 24, 2026
5 checks passed
@ritwik-g ritwik-g deleted the hotfix/presigned-url-max-length branch June 24, 2026 18:04
@sonarqubecloud

Copy link
Copy Markdown

@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This hotfix patches URLValidator.max_length to 8192 at the Django class level in base.py to prevent S3 pre-signed URLs carrying large X-Amz-Security-Token values (> 2048 chars) from failing DRF's URLField validation on the presigned_urls field.

  • The single-line class mutation (URLValidator.max_length = 8192) is applied globally at settings load time, affecting every URLField in the application — not only presigned_urls — which silently removes the 2048-char guard from other bare serializer URL fields (e.g. webhook url fields in notification_v2).
  • pyproject.toml pins django==4.2.30, but the fix only takes effect on Django 5.0+ (where URLValidator enforces max_length); the inline comment itself acknowledges the fix is a no-op on 4.2.x, so the production Django version should be verified and the dependency spec updated to match.

Confidence Score: 3/5

The fix may be inoperative: pyproject.toml pins Django 4.2.30, but the patch only has any effect on Django 5.0+, where URLValidator began enforcing a 2048-char ceiling. Until the actual production Django version is confirmed and the spec updated, merging this does not guarantee the reported failure stops.

The class-level mutation touches every URLField in the app, not just the presigned-URL path, and the version mismatch between pyproject.toml (4.2.30) and the targeted Django behaviour (5.0+) means the fix could silently do nothing in production while giving the appearance of being addressed.

backend/backend/settings/base.py and backend/pyproject.toml both need attention — the former for the scope of the global mutation, the latter because it must reflect the Django version actually running in production for the fix to be meaningful.

Important Files Changed

Filename Overview
backend/backend/settings/base.py Adds a global class-level monkey-patch raising URLValidator.max_length to 8192; effective only on Django 5.0+ but pyproject.toml pins django==4.2.30, creating a discrepancy that could leave the production fix inoperative

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant DRF as DRF Serializer
    participant UV as URLValidator (global)
    participant CV as Custom _validate_presigned_url

    Client->>DRF: "POST /api/deployment (presigned_urls=[long_s3_url])"
    DRF->>UV: URLField validation (child of ListField)
    Note over UV: Before fix: max_length=2048 → 2094-char URL fails
    Note over UV: After fix: max_length=8192 → passes
    UV-->>DRF: valid / ValidationError("Enter a valid URL.")
    DRF->>CV: validate_presigned_urls()
    CV->>CV: Check HTTPS scheme
    CV->>CV: Check .amazonaws.com S3 host
    CV-->>DRF: valid / ValidationError (scheme/host)
    DRF-->>Client: 200 OK / 400 Bad Request
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"}}}%%
sequenceDiagram
    participant Client
    participant DRF as DRF Serializer
    participant UV as URLValidator (global)
    participant CV as Custom _validate_presigned_url

    Client->>DRF: "POST /api/deployment (presigned_urls=[long_s3_url])"
    DRF->>UV: URLField validation (child of ListField)
    Note over UV: Before fix: max_length=2048 → 2094-char URL fails
    Note over UV: After fix: max_length=8192 → passes
    UV-->>DRF: valid / ValidationError("Enter a valid URL.")
    DRF->>CV: validate_presigned_urls()
    CV->>CV: Check HTTPS scheme
    CV->>CV: Check .amazonaws.com S3 host
    CV-->>DRF: valid / ValidationError (scheme/host)
    DRF-->>Client: 200 OK / 400 Bad Request
Loading

Fix All in Claude Code

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

---

### Issue 1 of 2
backend/backend/settings/base.py:27
**Dependency spec doesn't match targeted Django version**

`pyproject.toml` pins `django==4.2.30`, yet the inline comment on this very line says "No-op on Django 4.2.x (no such attribute is checked)." If production is actually running 4.2.30, the monkey-patch has no effect and the reported validation failure remains unfixed. The `pyproject.toml` should be updated to reflect the Django version that is genuinely deployed, so that the hotfix actually takes effect and future installs reproduce the prod configuration.

### Issue 2 of 2
backend/backend/settings/base.py:27
**Global class mutation widens validation for all URLField serializers**

Mutating `URLValidator.max_length` at class level raises the length ceiling for every `URLField` in the application — including the webhook `url` fields in `notification_v2/internal_serializers.py` — not just `presigned_urls`. Model-backed `URLField`s are protected by Django's `MaxLengthValidator(200)` that runs first, but bare DRF serializer `URLField()`s (like the webhook fields) lose the previous 2048-char guard. A more surgical alternative is to override the validator on the specific field. For a hotfix the global approach is pragmatic, but it's worth tracking a follow-up to scope it properly.

Reviews (1): Last reviewed commit: "[HOTFIX] Raise URLValidator max_length t..." | Re-trigger Greptile

# temporary/STS credentials (carrying X-Amz-Security-Token) routinely exceed this,
# causing "Enter a valid URL." on the API deployment `presigned_urls` field.
# Raise the cap globally. No-op on Django 4.2.x (no such attribute is checked).
URLValidator.max_length = 8192

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.

P1 Dependency spec doesn't match targeted Django version

pyproject.toml pins django==4.2.30, yet the inline comment on this very line says "No-op on Django 4.2.x (no such attribute is checked)." If production is actually running 4.2.30, the monkey-patch has no effect and the reported validation failure remains unfixed. The pyproject.toml should be updated to reflect the Django version that is genuinely deployed, so that the hotfix actually takes effect and future installs reproduce the prod configuration.

Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/backend/settings/base.py
Line: 27

Comment:
**Dependency spec doesn't match targeted Django version**

`pyproject.toml` pins `django==4.2.30`, yet the inline comment on this very line says "No-op on Django 4.2.x (no such attribute is checked)." If production is actually running 4.2.30, the monkey-patch has no effect and the reported validation failure remains unfixed. The `pyproject.toml` should be updated to reflect the Django version that is genuinely deployed, so that the hotfix actually takes effect and future installs reproduce the prod configuration.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

# temporary/STS credentials (carrying X-Amz-Security-Token) routinely exceed this,
# causing "Enter a valid URL." on the API deployment `presigned_urls` field.
# Raise the cap globally. No-op on Django 4.2.x (no such attribute is checked).
URLValidator.max_length = 8192

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.

P2 Global class mutation widens validation for all URLField serializers

Mutating URLValidator.max_length at class level raises the length ceiling for every URLField in the application — including the webhook url fields in notification_v2/internal_serializers.py — not just presigned_urls. Model-backed URLFields are protected by Django's MaxLengthValidator(200) that runs first, but bare DRF serializer URLField()s (like the webhook fields) lose the previous 2048-char guard. A more surgical alternative is to override the validator on the specific field. For a hotfix the global approach is pragmatic, but it's worth tracking a follow-up to scope it properly.

Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/backend/settings/base.py
Line: 27

Comment:
**Global class mutation widens validation for all URLField serializers**

Mutating `URLValidator.max_length` at class level raises the length ceiling for every `URLField` in the application — including the webhook `url` fields in `notification_v2/internal_serializers.py` — not just `presigned_urls`. Model-backed `URLField`s are protected by Django's `MaxLengthValidator(200)` that runs first, but bare DRF serializer `URLField()`s (like the webhook fields) lose the previous 2048-char guard. A more surgical alternative is to override the validator on the specific field. For a hotfix the global approach is pragmatic, but it's worth tracking a follow-up to scope it properly.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

ritwik-g pushed a commit that referenced this pull request Jun 24, 2026
* UN-3621 [HOTFIX] Structure tool no longer crashes when single-pass extraction returns a non-object output (#2110)

UN-3621 [FIX] Guard structure pipeline against non-dict single-pass output

Single-pass extraction can return a top-level JSON array (e.g. a truncated/
runaway LLM response that hit its output-token cap). The parsed `output` is
then a list, and _handle_structure_pipeline called `.values()` on it
unconditionally, raising an opaque `AttributeError: 'list' object has no
attribute 'values'` that failed the file with no actionable signal.

Guard the output shape: if it isn't a dict, return a clear ExecutionResult
failure naming the likely cause instead of crashing, and stop the malformed
payload from flowing downstream as a success.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* [HOTFIX] Raise URLValidator max_length to 8192 for long S3 presigned URLs (#2111)

---------

Co-authored-by: Kirtiman Mishra <110175055+kirtimanmishrazipstack@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c2f72b42-4e68-49b8-b35d-066607da8b1d

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/presigned-url-max-length

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.

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.