Phase 2 완료 (4개): - 노무관리, 단가관리(건설), 입금, 출금 Phase 3 라우팅 구조 변경 완료 (22개): - 거래처(영업), 팝업관리, 공정관리, 게시판관리, 대손추심, Q&A - 현장관리, 실행내역, 견적관리, 견적(테스트) - 입찰관리, 이슈관리, 현장설명회, 견적서(건설) - 협력업체, 시공관리, 기성관리, 품목관리(건설) - 회계 도메인: 거래처, 매출, 세금계산서, 매입 신규 컴포넌트: - ErrorCard: 에러 페이지 UI 통일 - ServerErrorPage: V2 페이지 에러 처리 필수 - V2 Client 컴포넌트 및 Config 파일들 총 47개 상세 페이지 중 28개 완료, 19개 제외/불필요 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.6 KiB
3.6 KiB
Chrome DevTools MCP - 이모지 JSON 직렬화 오류
작성일: 2025-01-17
문제 현상
Chrome DevTools MCP가 특정 페이지 접근 시 다운되는 현상
에러 메시지
API Error: 400 {"type":"error","error":{"type":"invalid_request_error",
"message":"The request body is not valid JSON: invalid high surrogate in string:
line 1 column XXXXX (char XXXXX)"},"request_id":"req_XXXXX"}
발생 조건
- 페이지에 이모지가 많이 포함된 경우
take_snapshot또는 다른 MCP 도구 호출 시- a11y tree를 JSON으로 직렬화하는 과정에서 발생
원인
유니코드 서로게이트 쌍 (Surrogate Pair) 문제
이모지는 UTF-16에서 서로게이트 쌍으로 인코딩됨:
- High surrogate: U+D800 ~ U+DBFF
- Low surrogate: U+DC00 ~ U+DFFF
Chrome DevTools MCP가 페이지 스냅샷을 JSON으로 직렬화할 때, 이모지의 서로게이트 쌍이 깨지면서 "invalid high surrogate" 오류 발생.
문제가 되는 케이스
- DOM에 직접 렌더링된 이모지:
<span>🏠</span> - 데이터에 포함된 이모지: API 응답, 파싱된 데이터
- 대량의 이모지: 수십 개 이상의 이모지가 한 페이지에 존재
해결 방법
1. 이모지를 Lucide 아이콘으로 교체 (UI)
Before
const iconMap = {
'기본': '🏠',
'인사관리': '👥',
};
<span className="text-xl">{category.icon}</span>
After
import { Home, Users, type LucideIcon } from 'lucide-react';
const iconComponents: Record<string, LucideIcon> = {
Home,
Users,
};
function CategoryIcon({ name }: { name: string }) {
const IconComponent = iconComponents[name] || FileText;
return <IconComponent className="w-5 h-5" />;
}
<CategoryIcon name={category.icon} />
2. 데이터 파싱 시 이모지 제거/변환 (Server)
function convertEmojiToText(text: string): string {
// 특정 이모지를 의미있는 텍스트로 변환
let result = text
.replace(/✅/g, '[완료]')
.replace(/⚠️?/g, '[주의]')
.replace(/🧪/g, '[테스트]')
.replace(/🆕/g, '[NEW]')
.replace(/•/g, '-');
// 모든 이모지 및 특수 유니코드 문자 제거
result = result
.replace(/[\u{1F300}-\u{1F9FF}]/gu, '') // 이모지 범위
.replace(/[\u{2600}-\u{26FF}]/gu, '') // 기타 기호
.replace(/[\u{2700}-\u{27BF}]/gu, '') // 딩뱃
.replace(/[\u{FE00}-\u{FE0F}]/gu, '') // Variation Selectors
.replace(/[\u{1F000}-\u{1F02F}]/gu, '') // 마작 타일
.replace(/[\u{1F0A0}-\u{1F0FF}]/gu, '') // 플레잉 카드
.replace(/[\u200D]/g, '') // Zero Width Joiner
.trim();
return result;
}
체크리스트
새 페이지 개발 시 Chrome DevTools MCP 호환성 확인:
- 페이지에 이모지 직접 렌더링하지 않음
- 아이콘은 Lucide 또는 SVG 사용
- 외부 데이터(API, 파일) 파싱 시 이모지 제거 처리
- status, label 등에 이모지 대신 텍스트 사용
관련 파일
이 문제로 수정된 파일들:
| 파일 | 변경 내용 |
|---|---|
dev/test-urls/actions.ts |
iconMap, convertEmojiToText 함수 추가 |
dev/test-urls/TestUrlsClient.tsx |
Lucide 아이콘 동적 렌더링 |
dev/construction-test-urls/actions.ts |
동일 |
dev/construction-test-urls/ConstructionTestUrlsClient.tsx |
동일 |
참고
- 이 문제는 Chrome DevTools MCP의 JSON 직렬화 로직에서 발생
- MCP 자체 버그일 가능성 있으나, 클라이언트에서 이모지 제거로 우회 가능
- 다른 MCP 도구에서도 비슷한 문제 발생 가능성 있음