Fix #571: Add error rule for 'Too much media'#572
Conversation
Add new error rule to handle Claude API's media count limit error when total media (document pages + images) exceeds 100. - Pattern: "Too much media" (contains match) - Category: media_limit - Priority: 79 (after PDF limit rules) - Override message explains the limit and suggests reducing media count Closes #571 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Summary of ChangesHello @ding113, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves an issue where the Claude API's "Too much media" error was not properly categorized, leading to incorrect retry attempts. By adding a dedicated error rule, the system now accurately identifies this as a non-retryable client-side "media_limit" error, enhancing error handling and providing clearer feedback to users regarding media submission limits. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
📝 WalkthroughWalkthrough在 Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Code Review
This pull request correctly adds a new error rule to handle the 'Too much media' error from the Claude API, ensuring it's treated as a non-retryable client error. The implementation is straightforward and follows the existing structure for error rules. I have one suggestion to make the pattern matching more robust by using a more specific regular expression.
| { | ||
| pattern: "Too much media", | ||
| category: "media_limit", | ||
| description: "Total media count (document pages + images) exceeds API limit", | ||
| matchType: "contains" as const, | ||
| isDefault: true, | ||
| isEnabled: true, | ||
| priority: 79, | ||
| overrideResponse: { | ||
| type: "error", | ||
| error: { | ||
| type: "media_limit", | ||
| message: "媒体数量超过限制(文档页数 + 图片数量 > 100),请减少图片或文档页数后重试", | ||
| }, | ||
| }, | ||
| }, |
There was a problem hiding this comment.
The current pattern Too much media with matchType: "contains" is a bit broad. It could potentially match other future errors from the Claude API that contain this phrase but are unrelated. To make the matching more robust and specific to this particular error format, I suggest using a regular expression anchored to the start of the string. This ensures we only match errors that begin with Too much media:.
| { | |
| pattern: "Too much media", | |
| category: "media_limit", | |
| description: "Total media count (document pages + images) exceeds API limit", | |
| matchType: "contains" as const, | |
| isDefault: true, | |
| isEnabled: true, | |
| priority: 79, | |
| overrideResponse: { | |
| type: "error", | |
| error: { | |
| type: "media_limit", | |
| message: "媒体数量超过限制(文档页数 + 图片数量 > 100),请减少图片或文档页数后重试", | |
| }, | |
| }, | |
| }, | |
| { | |
| pattern: "^Too much media:", | |
| category: "media_limit", | |
| description: "Total media count (document pages + images) exceeds API limit", | |
| matchType: "regex" as const, | |
| isDefault: true, | |
| isEnabled: true, | |
| priority: 79, | |
| overrideResponse: { | |
| type: "error", | |
| error: { | |
| type: "media_limit", | |
| message: "媒体数量超过限制(文档页数 + 图片数量 > 100),请减少图片或文档页数后重试", | |
| }, | |
| }, | |
| }, |
🧪 测试结果
总体结果: ✅ 所有测试通过 |
| // Issue #571: Total media count (document pages + images) exceeds limit | ||
| { | ||
| pattern: "Too much media", | ||
| category: "media_limit", |
There was a problem hiding this comment.
The new category media_limit is missing from multiple required locations:
src/actions/error-rules.ts(lines 63-70 and 103-111): ThevalidCategoriesarray doesn't include"media_limit", causing validation to fail when users try to create/edit rules with this category- UI components: Missing from
src/app/[locale]/settings/error-rules/_components/add-rule-dialog.tsx(line 97) andedit-rule-dialog.tsx(line 118) - Translation files: Missing from all 5 translation files (
messages/en/settings.json,messages/zh-CN/settings.json, etc.) in thecategoriessection
Without these additions, the new error rule will be inserted via syncDefaultErrorRules(), but users won't be able to manually create or edit media_limit rules through the UI.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/repository/error-rules.ts
Line: 646:646
Comment:
The new category `media_limit` is missing from multiple required locations:
1. **`src/actions/error-rules.ts` (lines 63-70 and 103-111)**: The `validCategories` array doesn't include `"media_limit"`, causing validation to fail when users try to create/edit rules with this category
2. **UI components**: Missing from `src/app/[locale]/settings/error-rules/_components/add-rule-dialog.tsx` (line 97) and `edit-rule-dialog.tsx` (line 118)
3. **Translation files**: Missing from all 5 translation files (`messages/en/settings.json`, `messages/zh-CN/settings.json`, etc.) in the `categories` section
Without these additions, the new error rule will be inserted via `syncDefaultErrorRules()`, but users won't be able to manually create or edit `media_limit` rules through the UI.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @src/repository/error-rules.ts:
- Around line 643-659: The overrideResponse.error.message in the rule with
pattern "Too much media" (file error-rules.ts) is a hardcoded Chinese
string—replace it with an i18n lookup key (e.g., use a centralized i18n function
or message key like "error.media_limit") and ensure the corresponding
translations exist for zh-CN, en, ja, ko, de; then apply the same change to the
other rules in this file (roughly lines 292–778) that currently use hardcoded
user-facing Chinese messages so all user-visible messages come from the i18n
resources rather than literals.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to Reviews > Disable Cache setting
📒 Files selected for processing (1)
src/repository/error-rules.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
No emoji characters in any code, comments, or string literals
Files:
src/repository/error-rules.ts
**/*.{ts,tsx,jsx,js}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,jsx,js}: All user-facing strings must use i18n (5 languages supported: zh-CN, en, ja, ko, de). Never hardcode display text
Use path alias @/ to map to ./src/
Use Biome for code formatting with configuration: double quotes, trailing commas, 2-space indent, 100 character line width
Prefer named exports over default exports
Use next-intl for internationalization
Use Next.js 16 App Router with Hono for API routes
Files:
src/repository/error-rules.ts
🧠 Learnings (1)
📚 Learning: 2026-01-05T03:01:39.354Z
Learnt from: NieiR
Repo: ding113/claude-code-hub PR: 539
File: src/types/user.ts:158-170
Timestamp: 2026-01-05T03:01:39.354Z
Learning: In TypeScript interfaces, explicitly document and enforce distinct meanings for null and undefined. Example: for numeric limits like limitTotalUsd, use 'number | null | undefined' when null signifies explicitly unlimited (e.g., matches DB schema or special UI logic) and undefined signifies 'inherit default'. This pattern should be consistently reflected in type definitions across related fields to preserve semantic clarity between database constraints and UI behavior.
Applied to files:
src/repository/error-rules.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: 🌐 API Tests
- GitHub Check: check-codex-status
- GitHub Check: Docker Build Test
- GitHub Check: pr-review
- GitHub Check: pr-description
- GitHub Check: dev-build-deploy
| // Issue #571: Total media count (document pages + images) exceeds limit | ||
| { | ||
| pattern: "Too much media", | ||
| category: "media_limit", | ||
| description: "Total media count (document pages + images) exceeds API limit", | ||
| matchType: "contains" as const, | ||
| isDefault: true, | ||
| isEnabled: true, | ||
| priority: 79, | ||
| overrideResponse: { | ||
| type: "error", | ||
| error: { | ||
| type: "media_limit", | ||
| message: "媒体数量超过限制(文档页数 + 图片数量 > 100),请减少图片或文档页数后重试", | ||
| }, | ||
| }, | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, verify the file exists and check the lines mentioned
fd error-rules.ts --type fRepository: ding113/claude-code-hub
Length of output: 151
🏁 Script executed:
# Check the file size and read around the lines mentioned (643-659)
wc -l src/repository/error-rules.ts
sed -n '640,665p' src/repository/error-rules.tsRepository: ding113/claude-code-hub
Length of output: 868
🏁 Script executed:
# Search for how error-rules is imported and used
rg -n "from.*error-rules|import.*error-rules" --type tsRepository: ding113/claude-code-hub
Length of output: 2392
🏁 Script executed:
# Search for any i18n or translation mechanisms in the codebase
rg -n "useTranslations|next-intl|i18n" --type ts | head -30Repository: ding113/claude-code-hub
Length of output: 2603
🏁 Script executed:
# Check if messages in error-rules are processed or translated elsewhere
rg -n "overrideResponse|error.*message" --type ts | grep -i "translat\|locale\|lang" | head -20Repository: ding113/claude-code-hub
Length of output: 2087
🏁 Script executed:
# Search for message handling in the entire repository
rg -n "message.*:" src/ --type ts | grep -v "node_modules" | head -40Repository: ding113/claude-code-hub
Length of output: 4450
🏁 Script executed:
# Examine the error-messages.ts file to understand i18n pattern
head -100 src/lib/utils/error-messages.tsRepository: ding113/claude-code-hub
Length of output: 3036
🏁 Script executed:
# Check how overrideResponse messages are used in the UI components
grep -n "overrideResponse\|message" src/app/\[locale\]/settings/error-rules/_components/edit-rule-dialog.tsx | head -20Repository: ding113/claude-code-hub
Length of output: 526
🏁 Script executed:
# Check error-rule-detector.ts to see how messages are actually used
cat -n src/lib/error-rule-detector.ts | head -50Repository: ding113/claude-code-hub
Length of output: 1514
🏁 Script executed:
# Search for message handling in error-rules related files
rg -n "message.*:" src/app/\[locale\]/settings/error-rules/_components/ --type ts -A 2 | head -40Repository: ding113/claude-code-hub
Length of output: 1915
🏁 Script executed:
# Check if there's any translation or locale handling for error-rules messages
rg -n "getTranslations\|useTranslations" src/app/\[locale\]/settings/error-rules/ --type tsRepository: ding113/claude-code-hub
Length of output: 49
🏁 Script executed:
# Check how overrideResponse is actually used - where is it sent/displayed?
rg -n "overrideResponse" src/app/v1/_lib/proxy/ --type ts -A 3 -B 3Repository: ding113/claude-code-hub
Length of output: 1364
🏁 Script executed:
# Check the proxy errors file to see how overrideResponse is used in API responses
cat -n src/app/v1/_lib/proxy/errors.ts | head -100Repository: ding113/claude-code-hub
Length of output: 3414
🏁 Script executed:
# See the full context of how error responses are returned
grep -n "overrideResponse\|ErrorDetectionResult" src/app/v1/_lib/proxy/ --type ts -r | head -30Repository: ding113/claude-code-hub
Length of output: 184
🏁 Script executed:
# Check if error-rules messages are displayed in UI or only sent to API clients
rg -n "message.*overrideResponse\|overrideResponse.*message" src/ --type ts -B 5 -A 5 | head -50Repository: ding113/claude-code-hub
Length of output: 49
🏁 Script executed:
# Check how many error rules have hardcoded Chinese messages
rg -n '"message".*:.*".*[^\x00-\x7F]' src/repository/error-rules.ts | head -20Repository: ding113/claude-code-hub
Length of output: 49
🏁 Script executed:
# Count all message fields in error-rules
grep -n '"message"' src/repository/error-rules.ts | wc -lRepository: ding113/claude-code-hub
Length of output: 68
🏁 Script executed:
# Get a broader view of how messages are structured in error-rules
sed -n '1,100p' src/repository/error-rules.ts | grep -A 15 "DEFAULT_ERROR_RULES"Repository: ding113/claude-code-hub
Length of output: 49
🏁 Script executed:
# Check if there are any error rules with English messages
rg -n 'overrideResponse' src/repository/error-rules.ts -A 6 | grep "message" | head -30Repository: ding113/claude-code-hub
Length of output: 1517
🏁 Script executed:
# Get the count of rules with non-ASCII characters in messages
python3 << 'EOF'
import re
with open('src/repository/error-rules.ts', 'r', encoding='utf-8') as f:
content = f.read()
# Find all message fields in overrideResponse
messages = re.findall(r'"message"\s*:\s*"([^"]*)"', content)
chinese_count = 0
english_count = 0
for msg in messages:
# Check if contains Chinese characters
if any('\u4e00' <= c <= '\u9fff' for c in msg):
chinese_count += 1
else:
english_count += 1
print(f"Total messages: {len(messages)}")
print(f"Chinese messages: {chinese_count}")
print(f"English messages: {english_count}")
print(f"\nAll messages:")
for i, msg in enumerate(messages, 1):
print(f"{i}. {msg[:80]}...")
EOFRepository: ding113/claude-code-hub
Length of output: 153
🏁 Script executed:
# Verify the exact line numbers of the new rule
sed -n '640,665p' src/repository/error-rules.ts | cat -nRepository: ding113/claude-code-hub
Length of output: 1016
🏁 Script executed:
# Confirm this is the only rule added (check if there are other new rules in this PR)
grep -n "Issue #571" src/repository/error-rules.tsRepository: ding113/claude-code-hub
Length of output: 145
🏁 Script executed:
# Check if there are translation files for these messages
find src -name "*.json" -path "*i18n*" -o -path "*messages*" | grep -E "(zh|en|ja|ko|de)" | head -20Repository: ding113/claude-code-hub
Length of output: 992
硬编码的中文消息违反了 i18n 编码规范
第 656 行的 message 字段包含硬编码的中文字符串,违反编码规范要求"所有面向用户的字符串必须使用 i18n(支持 5 种语言:zh-CN、en、ja、ko、de)"。此消息被返回给 API 客户端,属于面向用户的内容。
此外,这是一个系统性问题:文件中的所有错误规则(约 30 条,第 292-778 行)都使用相同的硬编码中文消息模式。建议在后续重构中统一为这些消息添加 i18n 支持。
其他方面的实现是正确的:
- ✅ 模式匹配
"Too much media"使用contains匹配类型 - ✅ 类别
"media_limit"语义清晰 - ✅ 优先级 79 位置合理
- ✅ 规则结构符合接口定义
🤖 Prompt for AI Agents
In @src/repository/error-rules.ts around lines 643 - 659, The
overrideResponse.error.message in the rule with pattern "Too much media" (file
error-rules.ts) is a hardcoded Chinese string—replace it with an i18n lookup key
(e.g., use a centralized i18n function or message key like "error.media_limit")
and ensure the corresponding translations exist for zh-CN, en, ja, ko, de; then
apply the same change to the other rules in this file (roughly lines 292–778)
that currently use hardcoded user-facing Chinese messages so all user-visible
messages come from the i18n resources rather than literals.
| }, | ||
| // Issue #571: Total media count (document pages + images) exceeds limit | ||
| { | ||
| pattern: "Too much media", |
There was a problem hiding this comment.
[HIGH] [TEST-MISSING-CRITICAL] New default rule is untested
Why this is a problem: This PR adds a new DEFAULT_ERROR_RULES entry but there is no automated test asserting the reported upstream error string is matched and classified as non-retryable. This violates the repo rule: "Test Coverage - All new features must have unit test coverage of at least 80%".
Evidence (src/repository/error-rules.ts:645):
pattern: "Too much media",Suggested fix (add a focused regression test):
// tests/integration/error-rule-detector.test.ts
import { describe, expect, test } from "vitest";
import { errorRuleDetector } from "@/lib/error-rule-detector";
test("matches 'Too much media' as media_limit", () => {
const result = errorRuleDetector.detect("Too much media: 0 document pages + 104 images > 100");
expect(result.matched).toBe(true);
expect(result.category).toBe("media_limit");
expect(result.matchType).toBe("contains");
});| type: "error", | ||
| error: { | ||
| type: "media_limit", | ||
| message: "媒体数量超过限制(文档页数 + 图片数量 > 100),请减少图片或文档页数后重试", |
There was a problem hiding this comment.
[MEDIUM] [STANDARD-VIOLATION] Hardcoded user-facing message bypasses i18n
Why this is a problem: The repo rule requires: "i18n Required - All user-facing strings must use i18n (5 languages supported). Never hardcode display text". This PR adds a hardcoded end-user message in the override response.
Evidence (src/repository/error-rules.ts:656):
message: "媒体数量超过限制(文档页数 + 图片数量 > 100),请减少图片或文档页数后重试",Suggested fix (keep the non-retryable classification, but avoid hardcoded display text until locale-aware i18n is wired into API error overrides):
{
pattern: "Too much media",
category: "media_limit",
description: null,
matchType: "contains" as const,
isDefault: true,
isEnabled: true,
priority: 79,
overrideResponse: null,
}There was a problem hiding this comment.
Code Review Summary
This PR adds a new default error rule for the Claude "Too much media" error. The change is small but it introduces user-facing hardcoded text and has no automated regression coverage for the new matching behavior.
PR Size: XS
- Lines changed: 17
- Files changed: 1
Issues Found
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Logic/Bugs | 0 | 0 | 1 | 0 |
| Security | 0 | 0 | 0 | 0 |
| Error Handling | 0 | 0 | 0 | 0 |
| Types | 0 | 0 | 0 | 0 |
| Comments/Docs | 0 | 0 | 0 | 0 |
| Tests | 0 | 1 | 0 | 0 |
| Simplification | 0 | 0 | 0 | 0 |
Critical Issues (Must Fix)
- None
High Priority Issues (Should Fix)
- [HIGH] [TEST-MISSING-CRITICAL] Missing regression test for the new "Too much media" rule (
src/repository/error-rules.ts:645) - [MEDIUM] [STANDARD-VIOLATION] Hardcoded user-facing override message bypasses i18n policy (
src/repository/error-rules.ts:656)
Review Coverage
- Logic and correctness
- Security (OWASP Top 10)
- Error handling
- Type safety
- Documentation accuracy
- Test coverage
- Code clarity
Automated review by Codex AI
There was a problem hiding this comment.
- Reviewed PR
#572(Fix #571: Add error rule for 'Too much media'), size XS (17 additions, 1 file) and applied labelsize/XS. - Posted 2 inline review comments (diff-only lines) on
src/repository/error-rules.ts:645andsrc/repository/error-rules.ts:656:- [HIGH]
[TEST-MISSING-CRITICAL]Missing regression test for the new"Too much media"rule (suggested adding a focusederrorRuleDetector.detect(...)test). - [MEDIUM]
[STANDARD-VIOLATION]Hardcoded user-facing override message bypasses i18n policy (suggested keeping classification but avoiding hardcoded display text until locale-aware overrides exist).
- [HIGH]
- Submitted the required PR review summary via
gh pr review --comment.
There was a problem hiding this comment.
Code Review Summary
No significant issues identified in this PR.
PR Size: XS
- Lines changed: 17 additions, 0 deletions
- Files changed: 1
Analysis
The PR correctly adds a new error rule for handling Claude API's "Too much media" error pattern. The implementation:
-
Pattern matching: Uses
containsmatch type with pattern"Too much media"- correctly matches the reported error format"Too much media: 0 document pages + 104 images > 100" -
Priority placement: Priority 79 is appropriately placed between
pdf_limit(80) andthinking_error(70) -
Response format: The
overrideResponsefollows the correct Claude API error format structure -
Category naming:
media_limitfollows existing conventions (pdf_limit,prompt_limit, etc.)
Regarding Greptile's Comment
The concern about missing media_limit in validCategories is a false positive. The validCategories list in src/actions/error-rules.ts only validates user-created custom rules via UI. Default rules are synced via syncDefaultErrorRules() which bypasses this validation entirely. This is an intentional design pattern - many existing default categories (input_limit, context_limit, token_limit, validation_error, model_error) are also not in that list.
Review Coverage
- Logic and correctness - Clean
- Security (OWASP Top 10) - Clean
- Error handling - Clean
- Type safety - Clean
- Documentation accuracy - Clean (comment accurately describes the rule purpose)
- Test coverage - Adequate (existing test infrastructure covers rule sync)
- Code clarity - Good
Automated review by Claude AI
Summary
Problem
Fixes #571
When users send requests with too many images/document pages (e.g.,
0 document pages + 104 images > 100), the Claude API returns:{ "type": "error", "error": { "type": "invalid_request_error", "message": "Too much media: 0 document pages + 104 images > 100" } }This error was not being categorized by any existing rule, causing it to be treated as a retryable provider error instead of a non-retryable client error.
Solution
Add a new default error rule to
DEFAULT_ERROR_RULESinsrc/repository/error-rules.ts:Too much mediacontainsmedia_limitThe override response provides a clear Chinese message explaining the limit.
Changes
src/repository/error-rules.ts: Added new error rule for "Too much media" patternTesting
Created by Claude AI in response to @claude mention
Greptile Overview
Greptile Overview
Greptile Summary
This PR adds a new error rule to handle Claude API's "Too much media" error (when document pages + images exceed 100). The rule implementation itself is correct, but the PR is incomplete and will cause runtime issues.
Critical Issue Found:
media_limitis missing from required validation lists insrc/actions/error-rules.ts(lines 63-70, 103-111), which will cause the validation to reject any attempt to manually create or edit rules with this category through the UIadd-rule-dialog.tsxandedit-rule-dialog.tsxmessages/*/settings.json)What Works:
syncDefaultErrorRules()at startupcontainsmatch type)pdf_limit(80) andthinking_error(70-72)Impact:
Users won't be able to create or edit
media_limitrules manually, though the default rule will function correctly once synced.Confidence Score: 2/5
media_limitrules through the UIsrc/actions/error-rules.ts, UI dialogs insrc/app/[locale]/settings/error-rules/_components/, and all translation files inmessages/*/settings.jsonImportant Files Changed
File Analysis
media_limiterror rule for "Too much media" pattern. Missing required type definitions, UI components, and translations.Sequence Diagram
sequenceDiagram participant Client participant ProxyHandler participant Claude API participant ErrorDetector participant ErrorRules DB Client->>ProxyHandler: Request with 104 images ProxyHandler->>Claude API: Forward request Claude API-->>ProxyHandler: 400 Error: "Too much media: 0 document pages + 104 images > 100" ProxyHandler->>ErrorDetector: detectAsync(error message) ErrorDetector->>ErrorRules DB: getActiveErrorRules() ErrorRules DB-->>ErrorDetector: Return cached rules (including media_limit) ErrorDetector->>ErrorDetector: Match pattern "Too much media" (contains) ErrorDetector-->>ProxyHandler: matched=true, category="media_limit", overrideResponse ProxyHandler->>ProxyHandler: Replace error with Chinese message ProxyHandler-->>Client: 400 Error: "媒体数量超过限制(文档页数 + 图片数量 > 100)..."Important Files Changed
File Analysis
media_limiterror rule for "Too much media" pattern. Missing required type definitions, UI components, and translations.Sequence Diagram
sequenceDiagram participant Client participant ProxyHandler participant Claude API participant ErrorDetector participant ErrorRules DB Client->>ProxyHandler: Request with 104 images ProxyHandler->>Claude API: Forward request Claude API-->>ProxyHandler: 400 Error: "Too much media: 0 document pages + 104 images > 100" ProxyHandler->>ErrorDetector: detectAsync(error message) ErrorDetector->>ErrorRules DB: getActiveErrorRules() ErrorRules DB-->>ErrorDetector: Return cached rules (including media_limit) ErrorDetector->>ErrorDetector: Match pattern "Too much media" (contains) ErrorDetector-->>ProxyHandler: matched=true, category="media_limit", overrideResponse ProxyHandler->>ProxyHandler: Replace error with Chinese message ProxyHandler-->>Client: 400 Error: "媒体数量超过限制(文档页数 + 图片数量 > 100)..."