Skip to content

Commit 069a177

Browse files
Deepak-Kesavankirtimanmishrazipstackclaude
authored
Reverse merge V0.176.4 hotfix (#2112)
* 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>
1 parent 6b3cfab commit 069a177

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

backend/backend/settings/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,17 @@
1515
from urllib.parse import quote
1616

1717
import httpx
18+
from django.core.validators import URLValidator
1819
from dotenv import find_dotenv, load_dotenv
1920
from utils.common_utils import CommonUtils
2021
from utils.cors_origin import normalize_web_app_origin
2122

23+
# Django 5.0+ caps URLValidator at 2048 chars. S3 pre-signed URLs signed with
24+
# temporary/STS credentials (carrying X-Amz-Security-Token) routinely exceed this,
25+
# causing "Enter a valid URL." on the API deployment `presigned_urls` field.
26+
# Raise the cap globally. No-op on Django 4.2.x (no such attribute is checked).
27+
URLValidator.max_length = 8192
28+
2229
missing_settings = []
2330

2431

workers/executor/executors/legacy_executor.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,19 @@ def _failure(child_result: ExecutionResult) -> ExecutionResult:
703703
)
704704

705705
output_map = structured_output.get(PSKeys.OUTPUT, {}) or {}
706+
if not isinstance(output_map, dict):
707+
# Single-pass can return a non-dict (e.g. a top-level JSON array) when the
708+
# LLM emits a truncated/runaway response. Fail clearly instead of crashing
709+
# on .values(), and keep the malformed shape from flowing downstream as a
710+
# success.
711+
return ExecutionResult.failure(
712+
error=(
713+
f"Single-pass extraction returned a {type(output_map).__name__}, "
714+
"expected a field map; the LLM likely produced a truncated or "
715+
"runaway response (check output-token usage)."
716+
),
717+
metadata={"usage_records": pipeline_records},
718+
)
706719
answered = sum(1 for v in output_map.values() if v not in (None, "", [], {}))
707720
shim.stream_log(f"Pipeline completed: {answered}/{len(outputs)} prompts answered")
708721
out_metadata = {

0 commit comments

Comments
 (0)