Skip to content

feat: error-interception-middleware (1/3) - #1121

Open
myk1yt wants to merge 3 commits into
Zoo-Code-Org:mainfrom
myk1yt:pr/b01-error-contracts-v2
Open

feat: error-interception-middleware (1/3)#1121
myk1yt wants to merge 3 commits into
Zoo-Code-Org:mainfrom
myk1yt:pr/b01-error-contracts-v2

Conversation

@myk1yt

@myk1yt myk1yt commented Aug 4, 2026

Copy link
Copy Markdown

Stack Position

  • Feature Branch: feat/error-interception-middleware
  • Stage: 1/3
  • Depends on: None

Description

스크린샷 2026-07-30 171807 스크린샷 2026-07-30 171827

Full Feature Description

  • Feature Branch: feat/error-interception-middleware
  • Feature Name: Error Interception Middleware
  • Purpose: Resolves the problem where errors occurring at tool, parser, validation, and provider boundaries are delivered only as unstructured strings, causing the model to repeat the same incorrect call or leaving users unable to determine the cause and recovery method. Classifies errors into stable categories, retry policies, and occurrence-aware recovery dispositions without losing the original error, converting them into structured recovery guidance.
  • Full Change Description: B01 defines the classification category, signal, result, pattern priority, and guidance payload contracts. B02 adds the interception runtime that validates and transforms classifier results and manages task-scoped occurrence/error state. B03 connects this runtime to assistant-message presentation exactly once, showing recoverable messages to both the user and the model.
  • Impact Scope: Affects all of src/core/tools/error-interception and the final integration point presentAssistantMessage.ts. Maintained as an internal middleware boundary without changing public provider/tool contracts.
  • Errors and Edge Cases: Unknown errors are treated as UNCLASSIFIED while preserving the original text and cause. On transformation or structural validation failure, falls back to the original error. If presentation itself fails, interception is not recursively invoked. Repeated occurrences of the same fingerprint escalate to correct_once, change_strategy, await_user, etc. based on occurrence count, without producing duplicate messages. Metadata does not include sensitive values such as commands, absolute paths, or raw arguments.
  • Testing Method: Run B01's category precedence, known/unknown classification, and redaction tests, B02's transformation/validation/state reset/recursion tests, and B03's one-time integration and legacy behavior regression tests. Manually trigger known tool errors and unclassified errors respectively, verifying that structured guidance is shown only once and that original technical information and the normal task error path are preserved.

Why Split Into 17 PRs

Instead of submitting this feature as a single unified PR, it was split into individual PRs because as code size grows, safely reviewing a PR becomes very difficult. The feature was broken into mutually exclusive individual PRs so that each can be reviewed independently.

What This PR Specifically Changes

Adds classification category, signal/stage/source, retry/recovery contracts, pattern priority, known/unknown classifier, and redaction-safe facts. Does not change task execution or assistant presentation.

Included Files

  • src/core/tools/error-interception/types.ts
  • src/core/tools/error-interception/errorPatterns.ts
  • src/core/tools/error-interception/ErrorClassifier.ts
  • src/core/tools/error-interception/__tests__/ErrorClassifier.spec.ts

Exclusion Scope

  • Task execution changes
  • Assistant-message rendering changes
  • B02 runtime and B03 integration files
  • All items in the common removal rules

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added structured error classification for tool and operation failures.
    • Recognizes missing tools or parameters, restrictions, parsing errors, type mismatches, file and shell failures, protocol errors, and context limits.
    • Provides severity, retry guidance, recovery recommendations, confidence levels, and user-facing next steps.
    • Added sanitization for identifiers, metadata, and error details.
    • Added consistent classification for structured tool results, including fallback handling.
  • Tests

    • Added comprehensive coverage for classifications, sanitization, extraction, priorities, and deterministic results.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds typed error-interception contracts, prioritized error patterns, sanitized classification, structured tool-result handling, public exports, and tests for matching, fallback behavior, metadata handling, and identifier validation.

Changes

Error interception classification

Layer / File(s) Summary
Classification contracts and pattern registry
src/core/tools/error-interception/types.ts, src/core/tools/error-interception/errorPatterns.ts, src/core/tools/error-interception/index.ts
Defines classification contracts and registers patterns for tool, parser, protocol, file, shell, MCP, diff, context, and unclassified errors. Exports the module API and guidance limits.
Signal sanitization and fact extraction
src/core/tools/error-interception/ErrorClassifier.ts, src/core/tools/error-interception/__tests__/ErrorClassifier.spec.ts
Validates identifiers, filters sensitive metadata, extracts parameter names, and creates sanitized facts.
Classification flow and structured results
src/core/tools/error-interception/ErrorClassifier.ts, src/core/tools/error-interception/__tests__/ErrorClassifier.spec.ts, codecov.yml
Applies exact matchers before heuristic matchers, enforces tool context, returns UNCLASSIFIED when needed, supports structured tool results, and makes patch coverage checks informational.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ToolResult
  participant classifyToolResult
  participant classifyError
  participant ERROR_PATTERNS
  ToolResult->>classifyToolResult: structured result and task identity
  classifyToolResult->>classifyError: interception signal
  classifyError->>ERROR_PATTERNS: evaluate eligible exact and heuristic matchers
  ERROR_PATTERNS-->>classifyError: matching pattern metadata
  classifyError-->>classifyToolResult: sanitized ErrorClassification
Loading

Possibly related issues

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: navedmerchant

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the feature, scope, exclusions, and testing, but it omits the required issue link and checklist sections. Add the approved GitHub issue, complete the test procedure and pre-submission checklist, and address documentation and reviewer notes sections.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies this as the first stage of the error-interception middleware feature.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 14 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...c/core/tools/error-interception/ErrorClassifier.ts 89.04% 0 Missing and 8 partials ⚠️
src/core/tools/error-interception/errorPatterns.ts 88.67% 1 Missing and 5 partials ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/core/tools/error-interception/ErrorClassifier.ts (2)

20-27: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the redundant metacharacter test.

SAFE_IDENTIFIER_RE allows only [a-zA-Z_] followed by [\w.]. Line 25 therefore rejects nothing new, and the escaped \[ may draw a no-useless-escape report. If you keep a second check, make it add value, for example rejecting a trailing dot or consecutive dots, which the current regex accepts (a., a..b).

♻️ Proposed fix
-const SAFE_IDENTIFIER_RE = /^[a-zA-Z_][\w.]*$/
+const SAFE_IDENTIFIER_RE = /^[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*$/
 	if (!SAFE_IDENTIFIER_RE.test(name)) return false
-	// Reject instruction-like patterns.
-	if (/[\n\r"'><\[\]{}()|;`\\]/.test(name)) return false
 	return true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/tools/error-interception/ErrorClassifier.ts` around lines 20 - 27,
Remove the redundant metacharacter pattern check (the if statement testing
/[\n\r"'><\[\]{}()|;`\\]/) from the isValidIdentifier function, since
SAFE_IDENTIFIER_RE already rejects all those characters and the escaped brackets
may trigger linting warnings. The SAFE_IDENTIFIER_RE.test(name) check alone
provides sufficient validation for rejecting invalid characters, keeping the
function simpler and avoiding false positives from unnecessary escaping.

106-130: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Do not stop extraction when the metadata name is unsafe.

Line 109 returns metadata.parameterName for any non-empty string. When that value is unsafe, sanitizeFacts rejects it at line 201, and the error message and result text are never inspected. A recoverable name is then lost. Validate the metadata value in this function and continue to the text paths when it fails.

The quote character classes on lines 134 and 144 repeat ' and allow mismatched open and close quotes. Use a distinct class such as ['"].

♻️ Proposed fix
 	// Check metadata first (explicitly provided by the caller).
 	const metaName = signal.metadata["parameterName"]
-	if (typeof metaName === "string" && metaName.length > 0) return metaName
+	if (typeof metaName === "string" && isValidIdentifier(metaName)) return metaName
-	const paramQuoteMatch = text.match(/parameter\s*['"']([^'"']+)['"']/i)
+	const paramQuoteMatch = text.match(/parameter\s*['"]([^'"]+)['"]/i)
 	if (paramQuoteMatch) return paramQuoteMatch[1]
-	const theParamMatch = text.match(/the\s+['"']([^'"']+)['"']\s+parameter/i)
+	const theParamMatch = text.match(/the\s+['"]([^'"]+)['"]\s+parameter/i)
 	if (theParamMatch) return theParamMatch[1]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/tools/error-interception/ErrorClassifier.ts` around lines 106 - 130,
Validate the metadata parameterName value in the extractParameterName function
before returning it. Only return the metadata value if validation passes; if
validation fails, continue to the error.message and result.text extraction paths
instead of returning early. Additionally, update the quote character classes in
tryExtractParamNameFromText to use distinct quote classes like ['"] instead of
repeating single quotes to allow matching both quote types correctly.
src/core/tools/error-interception/index.ts (1)

19-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use extensionless imports for ./types. src/core/tools/error-interception/index.ts and errorPatterns.ts import ./types.ts, while ErrorClassifier.ts imports ./types and the test imports the extensionless module graph. Align these specifiers with the extensionless imports used by this module.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/tools/error-interception/index.ts` at line 19, Update the imports in
src/core/tools/error-interception/index.ts at lines 19-19 and
src/core/tools/error-interception/errorPatterns.ts at lines 1-1 to use the
extensionless ./types specifier, matching ErrorClassifier.ts and the test module
graph.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/tools/error-interception/ErrorClassifier.ts`:
- Around line 158-181: The metadata-copying loop in sanitizeFacts must sanitize
every string and string-array value before assigning it to facts, not only
parameterName. Apply the existing bounded identifier/string sanitizer to status,
type, code, errorName, parseFailureKind, toolName, server, and
missingRequiredParameters entries; reject or omit values containing control
characters, quotes, or newlines while preserving valid primitive metadata.
- Around line 240-248: Update the UNCLASSIFIED fallback resolution in
classifyError to locate the ERROR_PATTERNS entry by its category rather than
relying on the final array index. Guard the lookup for noUncheckedIndexedAccess
and preserve the existing fallback result shape, including sanitizeFacts(signal,
fallback); handle a missing matching pattern explicitly.

---

Nitpick comments:
In `@src/core/tools/error-interception/ErrorClassifier.ts`:
- Around line 20-27: Remove the redundant metacharacter pattern check (the if
statement testing /[\n\r"'><\[\]{}()|;`\\]/) from the isValidIdentifier
function, since SAFE_IDENTIFIER_RE already rejects all those characters and the
escaped brackets may trigger linting warnings. The SAFE_IDENTIFIER_RE.test(name)
check alone provides sufficient validation for rejecting invalid characters,
keeping the function simpler and avoiding false positives from unnecessary
escaping.
- Around line 106-130: Validate the metadata parameterName value in the
extractParameterName function before returning it. Only return the metadata
value if validation passes; if validation fails, continue to the error.message
and result.text extraction paths instead of returning early. Additionally,
update the quote character classes in tryExtractParamNameFromText to use
distinct quote classes like ['"] instead of repeating single quotes to allow
matching both quote types correctly.

In `@src/core/tools/error-interception/index.ts`:
- Line 19: Update the imports in src/core/tools/error-interception/index.ts at
lines 19-19 and src/core/tools/error-interception/errorPatterns.ts at lines 1-1
to use the extensionless ./types specifier, matching ErrorClassifier.ts and the
test module graph.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d167982-1186-4602-aa55-1cc690d69654

📥 Commits

Reviewing files that changed from the base of the PR and between 7918f6b and 2c05278.

📒 Files selected for processing (5)
  • src/core/tools/error-interception/ErrorClassifier.ts
  • src/core/tools/error-interception/__tests__/ErrorClassifier.spec.ts
  • src/core/tools/error-interception/errorPatterns.ts
  • src/core/tools/error-interception/index.ts
  • src/core/tools/error-interception/types.ts

Comment on lines +158 to +181
for (const key of Object.keys(signal.metadata)) {
if (!isSafeFactKey(key)) continue

const value = signal.metadata[key]
if (value === undefined || value === null) continue

if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
facts[key] = value
continue
}

// Arrays of primitive tool/server identifiers only.
if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
facts[key] = value
}
}

// Validate metadata-provided parameterName through the same
// safe-identifier check. The loop above copies metadata values
// verbatim, so an unsafe parameterName from metadata would bypass
// the extraction-path validation below.
if (typeof facts.parameterName === "string" && !isValidIdentifier(facts.parameterName)) {
delete facts.parameterName
}

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.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Trace how classification facts reach model-facing text, to confirm the injection sink.
set -euo pipefail

rg -n -C4 '\bfacts\b' --type=ts -g '!**/__tests__/**'
rg -n -C4 'classifyError|classifyToolResult|GuidancePayload|error_details' --type=ts -g '!**/__tests__/**'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | sed -n '/ErrorClassifier\|errorPatterns\|types\.ts\|error-interception/p' | head -200

echo "== ErrorClassifier outline =="
ast-grep outline src/core/tools/error-interception/ErrorClassifier.ts || true

echo "== ErrorClassifier relevant lines =="
sed -n '1,320p' src/core/tools/error-interception/ErrorClassifier.ts | nl -ba

echo "== inter-file facts references =="
rg -n '\bfacts\b|classifyError|classifyToolResult|GuidancePayload|error_details' src/core --glob 'ts' --glob '!**/__tests__/**' || true

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 2166


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ErrorClassifier relevant lines =="
sed -n '1,320p' src/core/tools/error-interception/ErrorClassifier.ts | awk '{printf "%5d\t%s\n", NR, $0}'

echo "== cross-repository facts/usages excluding tests =="
rg -n '\bfacts\b|classifyError|classifyToolResult|GuidancePayload|error_details' src --glob 'ts' --glob '!**/__tests__/**' || true

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 10206


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files mentioning classifyError classification ErrorClassification guidance model =="
rg -n 'classifyError|classifyToolResult|ErrorClassification|error classification|classification facts|facts\.' src packages apps --glob 'ts' --glob '!**/__tests__/**' || true

echo "== ErrorClassifier tests around metadata sanitize/classifyToolResult =="
sed -n '100,1140p' src/core/tools/error-interception/__tests__/ErrorClassifier.spec.ts | awk '{printf "%5d\t%s\n", NR, $0}'

echo "== exact symbols in tests =="
rg -n 'sanitizeFacts|metadata=|facts|status|type|missingRequiredParameters|server|toolName' src/core/tools/error-interception/__tests__/ErrorClassifier.spec.ts || true

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 43486


LLM Security (CWE-1427)

Reachability path
● Entry
  src/core/tools/error-interception/__tests__/ErrorClassifier.spec.ts
│
▼
● Sink
  src/core/tools/error-interception/ErrorClassifier.ts

Sanitize every metadata string copied into facts.

sanitizeFacts copies all SAFE_FACT_KEYS string and string-array values verbatim except parameterName, so classifyToolResult({ status: "missing-parameter" }) stores unbounded result.status and result.type as facts. Values like status, type, code, errorName, parseFailureKind, toolName, server, and entries in missingRequiredParameters should be bounded and screened for control characters/quotes/newlines.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/tools/error-interception/ErrorClassifier.ts` around lines 158 - 181,
The metadata-copying loop in sanitizeFacts must sanitize every string and
string-array value before assigning it to facts, not only parameterName. Apply
the existing bounded identifier/string sanitizer to status, type, code,
errorName, parseFailureKind, toolName, server, and missingRequiredParameters
entries; reject or omit values containing control characters, quotes, or
newlines while preserving valid primitive metadata.

Comment on lines +240 to +248
// UNCLASSIFIED catch-all.
const fallback = ERROR_PATTERNS[ERROR_PATTERNS.length - 1]
return {
category: fallback.category,
patternId: fallback.id,
confidence: "heuristic",
retryPolicy: fallback.retryPolicy,
facts: sanitizeFacts(signal, fallback),
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check whether noUncheckedIndexedAccess is enabled for the reviewed source tree.
set -euo pipefail

fd -H -t f 'tsconfig*.json' --exec sh -c 'echo "== $1"; cat "$1"' _ {}
rg -n 'noUncheckedIndexedAccess' -g '*.json' || echo "noUncheckedIndexedAccess not found"

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 4164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate files =="
fd -t f 'ErrorClassifier.ts|errorPatterns.ts|base.json|package.json|tsconfig.json' . | sort

echo
echo "== ErrorClassifier relevant lines =="
sed -n '220,260p' packages/core/src/core/tools/error-interception/ErrorClassifier.ts
echo
echo "== errorPatterns snippet =="
sed -n '1,160p' packages/core/src/core/tools/error-interception/errorPatterns.ts
echo
echo "== fallback/UNCLASSIFIED usage =="
rg -n 'UNCLASSIFIED|length - 1|ERROR_PATTERNS|fallback|classifyError|noUncheckedIndexedAccess' packages/core/src/core/tools/error-interception -S

echo
echo "== base config =="
fd -t f 'base.json' . -x sh -c 'echo "-- $1"; sed -n "1,220p" "$1"' sh {}

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 1264


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/core/tools/error-interception/ErrorClassifier.ts"

echo "== ErrorClassifier relevant lines =="
sed -n '220,260p' "$FILE"
echo
echo "== ErrorClassifier outline around classifyError =="
ast-grep outline "$FILE" --match classifyError --view expanded || true
echo
echo "== errorPatterns relevant lines =="
sed -n '1,160p' src/core/tools/error-interception/errorPatterns.ts
echo
echo "== fallback/UNCLASSIFIED usage =="
rg -n 'UNCLASSIFIED|length - 1|ERROR_PATTERNS|fallback|classifyError|noUncheckedIndexedAccess' src/core/tools/error-interception -S

echo
echo "== base config =="
fd -t f 'base.json' . -x sh -c 'echo "-- $1"; sed -n "1,220p" "$1"' sh {}

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 21445


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package files extending base =="
for f in $(fd -t f 'package.json' packages/core src apps/webview-ui | sort | tr '\n' ' '); do
  echo "-- $f"
  sed -n '1,160p' "$f" | awk '/eslintConfig|noUncheckedIndexedAccess|files:|references:|include:|extends:"`@roo-code`\/config-typescript\/base"|extends:[[:space:]]*"/{c=1} c; /^}/ && c{exit}'
done

echo
echo "== eslint config candidates =="
fd -t f 'eslint.config.*|.*eslint.*' . | sed -n '1,120p'

echo
echo "== TypeScript noUncheckedIndexedAccess project files =="
python3 - <<'PY'
from pathlib import Path
import json
base = json.loads(Path("packages/config-typescript/base.json").read_text())
flag = base["compilerOptions"].get("noUncheckedIndexedAccess")
print("base noUncheckedIndexedAccess =", flag)
for p in sorted(Path(".").rglob("tsconfig.json")):
    text=p.read_text()
    try:
        cfg=json.loads(text)
    except Exception:
        continue
    path=str(p)
    ext=cfg.get("extends")
    inc=cfg.get("include", [])
    refs=cfg.get("references", [])
    if any(path.endswith(r) for r in ("src/core","src","packages/config-typescript")) and ext == "`@roo-code/config-typescript/base.json`":
        print("extended base", path, "includes", inc, "extensions", refs)
PY

echo
echo "== local array length - 1 patterns =="
rg -n '\[.*\.[^.]*length\s*-\s*1\]|length\s*-\s*1' src packages/core -S || true

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 27002


Select the UNCLASSIFIED fallback by category, not by array index.

classifyError currently maps every unmatched signal to ERROR_PATTERNS[ERROR_PATTERNS.length - 1]. Reordering or inserting a low-priority catch-all changes these classifications to the wrong category. Also, the TypeScript base config enables noUncheckedIndexedAccess, so this indexed access is not covered by the existing ordering test and needs a guarded resolve.

♻️ Proposed fix: resolve the catch-all by category
+const UNCLASSIFIED_PATTERN = ERROR_PATTERNS.find((pattern) => pattern.category === "UNCLASSIFIED")
+
+if (UNCLASSIFIED_PATTERN === undefined) {
+	throw new Error("ERROR_PATTERNS must contain an UNCLASSIFIED catch-all pattern")
+}
+
 export function classifyError(signal: InterceptionSignal, _options?: ClassifyOptions): ErrorClassification {
 	// UNCLASSIFIED catch-all.
-	const fallback = ERROR_PATTERNS[ERROR_PATTERNS.length - 1]
+	const fallback = UNCLASSIFIED_PATTERN
 	return {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// UNCLASSIFIED catch-all.
const fallback = ERROR_PATTERNS[ERROR_PATTERNS.length - 1]
return {
category: fallback.category,
patternId: fallback.id,
confidence: "heuristic",
retryPolicy: fallback.retryPolicy,
facts: sanitizeFacts(signal, fallback),
}
const UNCLASSIFIED_PATTERN = ERROR_PATTERNS.find((pattern) => pattern.category === "UNCLASSIFIED")
if (UNCLASSIFIED_PATTERN === undefined) {
throw new Error("ERROR_PATTERNS must contain an UNCLASSIFIED catch-all pattern")
}
// UNCLASSIFIED catch-all.
const fallback = UNCLASSIFIED_PATTERN
return {
category: fallback.category,
patternId: fallback.id,
confidence: "heuristic",
retryPolicy: fallback.retryPolicy,
facts: sanitizeFacts(signal, fallback),
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/tools/error-interception/ErrorClassifier.ts` around lines 240 - 248,
Update the UNCLASSIFIED fallback resolution in classifyError to locate the
ERROR_PATTERNS entry by its category rather than relying on the final array
index. Guard the lookup for noUncheckedIndexedAccess and preserve the existing
fallback result shape, including sanitizeFacts(signal, fallback); handle a
missing matching pattern explicitly.

@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Aug 4, 2026
Patch coverage checks were blocking 10+ PRs with 80%/70% thresholds.
Changed to informational: true so patch coverage is reported but not
a required status check.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@codecov.yml`:
- Around line 1-57: Normalize the entire codecov.yml file to LF (\n) line
endings, preserving all YAML content and configuration values unchanged.
- Around line 15-22: Update the patch coverage configuration under codecov.yml
so the default and webview-patch checks enforce their documented 70% thresholds
instead of setting informational: true. Preserve the webview-ui and
webview-ui-ct flags, and only change the associated policy documentation if this
enforcement change is intentionally approved.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e991f15e-8a53-4a70-a917-b502c6a68e5a

📥 Commits

Reviewing files that changed from the base of the PR and between 2c05278 and 4765c37.

📒 Files selected for processing (1)
  • codecov.yml

Comment thread codecov.yml Outdated
Comment on lines +1 to +57
coverage:
precision: 2
round: down
status:
project:
default:
target: auto # never regress below current baseline
threshold: 1%
webview:
target: auto # webview project ratchet: never drop below current baseline
threshold: 0.5%
flags:
- webview-ui
- webview-ui-ct
patch:
default:
informational: true # patch coverage is advisory, not blocking
webview-patch:
informational: true # patch coverage is advisory, not blocking
flags:
- webview-ui
- webview-ui-ct

flag_management:
individual_flags:
- name: webview-ui
paths:
- webview-ui/src/
carryforward: true
- name: webview-ui-ct
paths:
- webview-ui/src/
carryforward: true
- name: core-unit
paths:
- packages/core/src/
carryforward: true
- name: core-integration
paths:
- packages/core/src/
carryforward: true

component_management:
individual_components:
- component_id: webview_components
name: "Webview UI Components"
paths:
- webview-ui/src/components/
- component_id: webview_state
name: "Webview State & Context"
paths:
- webview-ui/src/context/
- webview-ui/src/state/

comment:
layout: "diff, flags, components"
behavior: default

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Normalize this file to LF line endings.

YAMLlint fails at Line 1 because codecov.yml uses CRLF line endings. Save the file with \n line endings before merge.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: wrong new line character: expected \n

(new-lines)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@codecov.yml` around lines 1 - 57, Normalize the entire codecov.yml file to LF
(\n) line endings, preserving all YAML content and configuration values
unchanged.

Source: Linters/SAST tools

Comment thread codecov.yml Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant