Skip to content

Reverse merge V0.176.4 hotfix#2112

Merged
ritwik-g merged 2 commits into
mainfrom
v0.176.4-hotfix
Jun 24, 2026
Merged

Reverse merge V0.176.4 hotfix#2112
ritwik-g merged 2 commits into
mainfrom
v0.176.4-hotfix

Conversation

@Deepak-Kesavan

Copy link
Copy Markdown
Contributor

What

  • Reverse merge V0.176.4 hotfix

Why

How

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

Database Migrations

Env Config

Relevant Docs

Related Issues or PRs

Dependencies Versions

Notes on Testing

Screenshots

Checklist

I have read and understood the Contribution Guidelines.

kirtimanmishrazipstack and others added 2 commits June 24, 2026 21:29
…traction 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>
@Deepak-Kesavan Deepak-Kesavan requested a review from ritwik-g June 24, 2026 18:07
@Deepak-Kesavan Deepak-Kesavan self-assigned this Jun 24, 2026
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f7b27acd-4f8c-468c-a411-ccd5caf25cba

📥 Commits

Reviewing files that changed from the base of the PR and between 6b3cfab and 8b3243c.

📒 Files selected for processing (2)
  • backend/backend/settings/base.py
  • workers/executor/executors/legacy_executor.py

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of long URLs during deployment and validation, preventing valid pre-signed links from being incorrectly rejected.
    • Added safer processing for structured responses so unexpected output formats now fail gracefully with a clear error instead of causing downstream issues.

Walkthrough

Two independent bug fixes: Django settings now globally sets URLValidator.max_length = 8192 to prevent rejection of long pre-signed S3 URLs. LegacyExecutor._handle_structure_pipeline now checks that output_map is a dict before processing, returning ExecutionResult.failure with usage_records metadata when it is not.

Changes

Django URLValidator max_length override

Layer / File(s) Summary
URLValidator cap in settings
backend/backend/settings/base.py
Imports URLValidator and sets max_length = 8192 globally, overriding the Django 5.0+ default that would reject long pre-signed S3 URLs.

LegacyExecutor non-dict output guard

Layer / File(s) Summary
Non-dict output_map failure path
workers/executor/executors/legacy_executor.py
Adds a isinstance(output_map, dict) check after single-pass LLM output is retrieved; returns ExecutionResult.failure with a descriptive message and pipeline_records as usage_records in metadata when the output is not a dict, preventing a crash on .values().

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description uses the template but most required sections are empty placeholders rather than substantive content. Fill in What, Why, How, breaking-change impact, testing notes, and any relevant issues or version details instead of dashes.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is related to the merge but is too generic to describe the actual hotfix changes.
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.

✏️ 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 v0.176.4-hotfix

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.

@ritwik-g ritwik-g merged commit 069a177 into main Jun 24, 2026
19 of 20 checks passed
@ritwik-g ritwik-g deleted the v0.176.4-hotfix branch June 24, 2026 18:09
@sonarqubecloud

Copy link
Copy Markdown

@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This reverse-merge of the v0.176.4 hotfix brings two targeted bug fixes into main: a global URLValidator length-cap increase to fix S3 pre-signed URL validation failures, and a defensive type-guard in the legacy executor to handle malformed (non-dict) LLM output gracefully.

  • backend/backend/settings/base.py: Sets URLValidator.max_length = 8192 at class level to fix "Enter a valid URL." errors on the presigned_urls API field when S3 STS-signed URLs exceed Django 5.0+'s default 2048-char cap. This is a no-op on Django 4.2.x where the attribute is not yet checked.
  • workers/executor/executors/legacy_executor.py: Adds an isinstance(output_map, dict) check after single-pass extraction; rather than crashing on .values(), it now returns a clear ExecutionResult.failure with usage records preserved and a diagnostic message pointing to token-limit issues.

Confidence Score: 5/5

Both changes are safe to merge — they are narrow, well-commented hotfixes with no new risky code paths.

The URLValidator.max_length patch is a one-liner applied at import time and is already inert on the current Django 4.2.x baseline, activating only on upgrade to Django 5.0+. The isinstance guard in the legacy executor adds a clear failure path with preserved usage records, replacing a crash; the success path and all surrounding logic are unchanged.

No files require special attention. The global class mutation in base.py is intentional and well-scoped.

Important Files Changed

Filename Overview
backend/backend/settings/base.py Adds a global URLValidator.max_length = 8192 override at import time to accommodate S3 pre-signed URLs with STS/temporary credentials that exceed Django 5.0+'s 2048-char default limit.
workers/executor/executors/legacy_executor.py Adds an isinstance(output_map, dict) guard after single-pass extraction; returns a descriptive ExecutionResult.failure instead of crashing on .values() when the LLM emits a non-dict top-level result.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[LLM Single-Pass Extraction] --> B[answer_result.data = structured_output]
    B --> C[_finalize_pipeline_result\nadd metadata/metrics]
    C --> D[output_map = structured_output.get PSKeys.OUTPUT]
    D --> E{isinstance output_map dict?}
    E -- No --> F[ExecutionResult.failure\ntype error + usage_records\nfrom pipeline_records]
    E -- Yes --> G[Count answered prompts\nstream_log]
    G --> H[ExecutionResult success\nwith structured_output]

    subgraph Django URL Validation
        I[API: presigned_urls field\nS3 STS pre-signed URL] --> J{URLValidator\nmax_length check}
        J -- Django 5.0+ default 2048 --> K[ValidationError: Enter a valid URL]
        J -- Patched to 8192 --> L[Validation passes]
    end
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[LLM Single-Pass Extraction] --> B[answer_result.data = structured_output]
    B --> C[_finalize_pipeline_result\nadd metadata/metrics]
    C --> D[output_map = structured_output.get PSKeys.OUTPUT]
    D --> E{isinstance output_map dict?}
    E -- No --> F[ExecutionResult.failure\ntype error + usage_records\nfrom pipeline_records]
    E -- Yes --> G[Count answered prompts\nstream_log]
    G --> H[ExecutionResult success\nwith structured_output]

    subgraph Django URL Validation
        I[API: presigned_urls field\nS3 STS pre-signed URL] --> J{URLValidator\nmax_length check}
        J -- Django 5.0+ default 2048 --> K[ValidationError: Enter a valid URL]
        J -- Patched to 8192 --> L[Validation passes]
    end
Loading

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

@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 17.0
unit-core unit 0 0 4 0 1.2
unit-platform-service unit 9 0 1 0 1.3
unit-prompt-service unit 15 0 0 0 20.1
unit-rig unit 53 0 0 0 3.3
unit-runner unit 11 0 0 0 3.5
unit-sdk1 unit 390 0 0 0 20.8
unit-tool-registry unit 0 0 1 0 1.2
unit-workers unit 0 0 0 0 18.5
TOTAL 542 12 6 3 87.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

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.

3 participants