Files
sam-react-prod/claudedocs/dev/[REF] chrome-devtools-mcp-emoji-issue.md
유병철 1d7b028693 feat(WEB): Phase 2-3 V2 마이그레이션 완료 및 ServerErrorPage 적용
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>
2026-01-19 17:31:28 +09:00

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" 오류 발생.

문제가 되는 케이스

  1. DOM에 직접 렌더링된 이모지: <span>🏠</span>
  2. 데이터에 포함된 이모지: API 응답, 파싱된 데이터
  3. 대량의 이모지: 수십 개 이상의 이모지가 한 페이지에 존재

해결 방법

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 도구에서도 비슷한 문제 발생 가능성 있음