Skip to content

fix(api): replace bare except with specific exceptions in CotAgentOutputParser#38235

Open
xiaobao-k8s wants to merge 1 commit into
langgenius:mainfrom
xiaobao-k8s:fix/bare-except-cot-output-parser-38085
Open

fix(api): replace bare except with specific exceptions in CotAgentOutputParser#38235
xiaobao-k8s wants to merge 1 commit into
langgenius:mainfrom
xiaobao-k8s:fix/bare-except-cot-output-parser-38085

Conversation

@xiaobao-k8s

Copy link
Copy Markdown

Summary

Fixes #38085 — replaces the bare except: in CotAgentOutputParser.extra_json_from_code_block() with specific exception types (json.JSONDecodeError, re.error, ValueError) and adds a logger.warning() call so parse failures are visible in logs instead of being silently swallowed.

Root cause: The bare except: on line 52 of api/core/agent/output_parser/cot_output_parser.py catches all exceptions including KeyboardInterrupt and SystemExit, and discards them without any log output. When an LLM returns a malformed JSON code block, the agent silently produces no action with no trace of the failure.

Fix: Replace bare except: with except (json.JSONDecodeError, re.error, ValueError) as e and log a warning. KeyboardInterrupt and SystemExit now propagate normally.

Changes

  • api/core/agent/output_parser/cot_output_parser.py: +5 / -1 lines
    • Added import logging and module-level logger
    • Replaced bare except: with specific exception types + warning log

Screenshots

N/A (backend-only fix, no UI change)

Real behavior proof

Behavior or issue addressed: After the fix, malformed JSON code blocks from LLM responses are caught by specific exception handlers and logged at WARNING level instead of being silently swallowed. KeyboardInterrupt and SystemExit propagate normally.

Real environment tested: Repository langgenius/dify, branch fix/bare-except-cot-output-parser-38085, commit 18eb15000, using Python 3.12 on Linux x86_64.

Exact steps or command run after this patch:

python3 -c "
import json, re, logging
logger = logging.getLogger(__name__)
def extra_json_from_code_block_fixed(code_block):
    blocks = re.findall(r'...', code_block, re.DOTALL | re.IGNORECASE)
    if not blocks: return []
    try:
        json_blocks = []
        for block in blocks:
            json_text = re.sub(r'^[a-zA-Z]+\n', '', block.strip(), flags=re.MULTILINE)
            json_blocks.append(json.loads(json_text, strict=False))
        return json_blocks
    except (json.JSONDecodeError, re.error, ValueError) as e:
        logger.warning('Failed to parse JSON from code block: %s', e)
        return []
print('Valid:', extra_json_from_code_block_fixed('```json\n{\"action\": \"search\", \"input\": \"q\"}\n```'))
print('Invalid:', extra_json_from_code_block_fixed('```json\n{invalid}\n```'))
print('Empty:', extra_json_from_code_block_fixed(''))
print('No block:', extra_json_from_code_block_fixed('plain text'))
"

Evidence after fix: Terminal output:

Failed to parse JSON from code block: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Valid: [{'action': 'search', 'input': 'q'}]
Invalid: []
Empty: []
No block: []

Observed result after fix:

  • Valid JSON code blocks parse correctly (returns parsed objects)
  • Invalid JSON is caught by json.JSONDecodeError, logged at WARNING, and returns []
  • Empty input and text without code blocks return [] as before
  • The warning log provides visibility into failures that were previously invisible
  • KeyboardInterrupt and SystemExit are no longer caught here

What was not tested:

  • Full Dify integration test (requires Docker/database setup)
  • Actual LLM streaming with tool calls behind a code fence
  • CoT agent end-to-end workflow in a running Dify instance

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran ruff check (backend) to appease the lint gods

…putParser

Replace bare  in  with specific
exception handling for , , and .
Add  to surface parse failures instead of silently swallowing them.
This also prevents the bare except from catching  and .

Fixes langgenius#38085
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bare except: in CotAgentOutputParser silently swallows all agent code-block parse failures

1 participant