Conversation
Agent-Logs-Url: https://github.com/nexiouscaliver/OmniForge/sessions/c6a3be97-1717-43f0-96a7-61f840a35a1f Co-authored-by: nexiouscaliver <66136088+nexiouscaliver@users.noreply.github.com>
Agent-Logs-Url: https://github.com/nexiouscaliver/OmniForge/sessions/c6a3be97-1717-43f0-96a7-61f840a35a1f Co-authored-by: nexiouscaliver <66136088+nexiouscaliver@users.noreply.github.com>
glab MR metadata JSON in _fetch_mr_data
nexiouscaliver
left a comment
There was a problem hiding this comment.
Try json recovery incase of parsing error and retry then if not recoverable then return error.
There was a problem hiding this comment.
Pull request overview
Hardens _fetch_mr_data against malformed JSON output from glab mr view -F json to prevent uncaught JSONDecodeError crashes and instead return a stable, structured tool error response.
Changes:
- Wrap MR metadata JSON deserialization in
try/except json.JSONDecodeErrorand return a structuredparse_errorpayload on failure. - Add a regression test that simulates malformed
glabJSON output and asserts the function exits early without downstream subprocess calls.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
plugins/omniforge/tools/omniforge_mcp_server.py |
Adds JSON parsing guardrail and returns a structured parse_error response instead of raising. |
plugins/omniforge/tests/test_fetch_mr_data.py |
Adds test coverage for malformed MR metadata JSON and ensures no further subprocess calls occur. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Agent-Logs-Url: https://github.com/nexiouscaliver/OmniForge/sessions/7f1bc4d3-bffd-4fd0-a315-4cd2244413ba Co-authored-by: nexiouscaliver <66136088+nexiouscaliver@users.noreply.github.com>
Agent-Logs-Url: https://github.com/nexiouscaliver/OmniForge/sessions/7f1bc4d3-bffd-4fd0-a315-4cd2244413ba Co-authored-by: nexiouscaliver <66136088+nexiouscaliver@users.noreply.github.com>
Implemented in f99462c. |
glab MR metadata JSON in _fetch_mr_dataglab MR metadata JSON in _fetch_mr_data with recovery and retry
nexiouscaliver
left a comment
There was a problem hiding this comment.
In the recovery we inject mr_id (which is declared string) into cmd exec, kindly add safegards to prevent code injection using bash script in this variable and bypass security.
Agent-Logs-Url: https://github.com/nexiouscaliver/OmniForge/sessions/3dfb074c-b731-4c2e-a5f5-f3b750a91708 Co-authored-by: nexiouscaliver <66136088+nexiouscaliver@users.noreply.github.com>
Agent-Logs-Url: https://github.com/nexiouscaliver/OmniForge/sessions/3dfb074c-b731-4c2e-a5f5-f3b750a91708 Co-authored-by: nexiouscaliver <66136088+nexiouscaliver@users.noreply.github.com>
Agent-Logs-Url: https://github.com/nexiouscaliver/OmniForge/sessions/3dfb074c-b731-4c2e-a5f5-f3b750a91708 Co-authored-by: nexiouscaliver <66136088+nexiouscaliver@users.noreply.github.com>
Agent-Logs-Url: https://github.com/nexiouscaliver/OmniForge/sessions/3dfb074c-b731-4c2e-a5f5-f3b750a91708 Co-authored-by: nexiouscaliver <66136088+nexiouscaliver@users.noreply.github.com>
Added in 54a5900 (with follow-up cleanup in 2c60c8b and typing/docs in 6a876e2). |
glab MR metadata JSON in _fetch_mr_data with recovery and retryglab MR metadata JSON in _fetch_mr_data with recovery, retry, and mr_id command safeguards
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def parse_json_with_recovery(raw_json: str) -> tuple: | ||
| """Parse JSON with recovery for prefixed/suffixed non-JSON text. | ||
|
|
||
| Returns: | ||
| tuple[bool, object | None]: | ||
| (True, parsed_json) when parsing succeeds, otherwise (False, None). | ||
| """ |
There was a problem hiding this comment.
parse_json_with_recovery advertises a structured return in the docstring (tuple[bool, object | None]) but the function signature is annotated as -> tuple, which loses the type information and is inconsistent with the rest of this module’s more specific annotations (e.g., list[str]). Consider updating the return annotation to the actual tuple shape (using Any for the JSON value if desired) so callers and type checkers can rely on it.
| try: | ||
| initial_cmd = build_mr_view_json_cmd(mr_id) | ||
| except ValueError as e: | ||
| return {"success": False, "error": str(e), "error_type": "validation_error"} |
There was a problem hiding this comment.
_fetch_mr_data already validates mr_id before this block, but build_mr_view_json_cmd() re-validates and the surrounding try/except ValueError becomes effectively unreachable. To reduce duplication and simplify control flow, either (a) make build_mr_view_json_cmd() assume an already-validated mr_id (no internal validation) and remove this try/except, or (b) stop validating mr_id earlier and rely on the helper once (keeping validation centralized in one place).
| metadata_ok, metadata = parse_json_with_recovery(mr_json.stdout) | ||
| if not metadata_ok: | ||
| mr_json_retry = await run_exec(initial_cmd, cwd=repo_root) | ||
| if mr_json_retry.returncode == 0: | ||
| metadata_ok, metadata = parse_json_with_recovery(mr_json_retry.stdout) |
There was a problem hiding this comment.
The retry-success path (first glab mr view -F json output unrecoverable, second attempt returns valid/recoverable JSON) isn’t covered by tests. Adding a focused test for “recover on retry” would validate the new bounded retry behavior and expected subprocess call count (auth + 2x mr view + remaining calls).
_fetch_mr_dataassumedglab mr view -F jsonalways returned valid JSON and could raise an uncaughtJSONDecodeError, crashing the MCP tool path. This change hardens that boundary by adding JSON recovery and a single retry before returning a structured parse error, and adds defense-in-depth safeguards formr_idcommand construction.Error handling
glab mr view -F jsononce and parse/recover again.success: falseerror_type: "parse_error"error: "Failed to parse MR metadata JSON."Security hardening
validation_errorhandling if command construction fails validation.Regression coverage
test_fetch_mr_data.pyfor:parse_errormr_idinput being rejected before any subprocess call