Windows나 Excel에서 작성된 일본어 CSV 파일은 UTF-8이 아닌 CP932 (Microsoft의 Shift_JIS 확장)인 경우가 많습니다. Claude Code 2.1.322로 이 CSV 파일을 Read하게 하면 일본어가 � (U+FFFD)로 깨지고, Edit는 거부됩니다. 스크립트로 읽을 때는 encoding="cp932"를 지정하고, Claude Code에서 편집할 때는 먼저 UTF-8로 변환해야 합니다.
Write 기능 역시 이번 2.1.322에서는 기존의 CP932 파일을 거부했습니다. 공식 문서와는 다른 결과이므로, 이 점을 포함하여 동일한 네 가지 파일을 Claude Code의 Read / Edit / Write 기능과 pandas / iconv를 사용하여 비교 기록을 남깁니다.
확인 환경
확인 조건: Claude Code 2.1.322/Python 3.13.5 (pandas 3.0.6, chardet 5.2.0, charset_normalizer 3.5.2)/iconv/Linux 6.12/2026-11-11
Claude Code 호출은 다음 형식을 사용합니다. 모델은 haiku입니다. 기사에 적힌 에러 문구는 툴이 반환한 원문입니다. Edit와 Write 테스트에서는 --permission-mode acceptEdits를 사용했으며, 대상은 복사된 파일로 한정했습니다.
claude -p --output-format stream-json --verbose \
--setting-sources project --tools Read \
--permission-mode dontAsk --strict-mcp-config \
...
테스트한 파일은 다음 네 가지입니다. 모두 '상품,수량,금액' 형식의 작은 표입니다.
sales_cp932.csv
: CP932. 3행지에 '공식㈱테스트'. BOM 없음 -
sales_shift_jis_safe.csv
: 표준 Shift_JIS로도 인코딩 가능한 문자만 포함 (㈱ 없음). 3행지는 '미かん' -
sales_utf8.csv
: UTF-8, BOM 없음. ㈱ 있음 -
sales_utf8sig.csv
: UTF-8, 시작이 EF BB BF (BOM). ㈱ 있음
미확인 사항: Windows 환경의 Claude Code, Excel에서 CSV를 열었을 때의 표시, haiku 외의 모델.
증상 1: pandas의 기본 설정으로는 UTF-8로 실패함
pandas.read_csv("sales_cp932.csv")
(및 encoding="utf-8")는 다음 에러로 중단되었습니다.
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8f in position 0: invalid start byte
반면, encoding="cp932"를 사용하면 열 이름과 '공식㈱테스트' 모두 올바르게 읽혔습니다. 한편, 같은 파일을 encoding="shift_jis"로 읽으려고 하면 ㈱ 위치에서 실패합니다.
UnicodeDecodeError: 'shift_jis' codec can't decode byte 0x87 in position 32: illegal multibyte sequence
'㈱'(U+3231)은 CP932에는 존재하지만, 표준 shift_jis에는 없습니다. Python에서 shift_jis로 인코딩하려고 하면 UnicodeEncodeError가 발생했습니다. Excel에서 비롯된 CSV를 임시방편으로 shift_jis로 지정할 경우, 여기서 실패하는 경우가 있습니다.
증상 2: Claude Code의 Read는 에러를 내지 않고 U+FFFD로 표시함
동일한 sales_cp932.csv를 Read했을 때, 툴은 에러를 발생시키지 않고 다음과 같이 반환했습니다. 일본어 문자는 대체 문자(U+FFFD)가 되었고, 끝에 주의문이 붙었습니다.
1 ���i,����,���z
2 ���,2,300
3 �������e�X�g,1,100
...
비교하자면, sales_utf8.csv는 에러 없이 상품명과 ㈱ 모두 그대로 읽혔습니다. sales_utf8sig.csv
표시상으로는 같은 내용으로 읽을 수 있었습니다. 이 부분은 파일의 시작 바이트열이 EF BB BF라는 것을 별도로 확인했습니다. Read 출력에서는 BOM(Byte Order Mark)이 보이지 않았습니다.
증상 3: Edit과 Write 모두 기존 CP932 파일을 거부함
복사한 sales_cp932_edit.csv를 Read 한 후, Edit에서 'りんご'를 'みかん'으로 치환하려고 시도했을 때 다음 메시지로 인해 거부되었습니다. 치환 전후의 파일은 동일한 해시 값을 가지며 내용상 변화가 없습니다.
File is not valid UTF-8: it uses a legacy encoding such as Windows-1252, Shift-JIS or GBK, or it is binary. These tools write UTF-8 (or UTF-16LE behind its byte-order mark) and never convert a file's encoding on their own, so nothing was written. If the file is text, make the change with a shell command that reads and writes it in its own encoding (iconv, or PowerShell Get-Content/Set-Content -Encoding), or ask the user whether to convert it to UTF-8 first. To replace the whole file with new UTF-8 text anyway, delete it first, then Write it.
기존 CP932 파일에 대한 Write 시도 역시 동일한 계열의 메시지로 거부되었고, 파일은 변경되지 않았습니다. 작성하려 한 것은 UTF-8로 된 1줄 hello와 Read 후 지시했던 일본어 2줄(商品,数量,金額 및 みかん,1,100) 두 가지 경우입니다. 메시지 끝에는 '먼저 삭제한 후에 Write하면 UTF-8로 대체될 수 있다'고 되어 있지만, 삭제 후의 Write는 시도하지 않았습니다.
원인: Edit은 UTF-8로 되돌리기 위해 거부하고, Write는 공식 설명과 상이함
공식 도구 설명(Tools reference, 2026-11-11 조회)에 따르면, Read는 UTF-8로 해석할 수 없는 바이트를 U+FFFD로 표시하며, Edit은 UTF-8이 아닌 파일을 거부합니다. 이는 파일 전체를 UTF-8로 되돌려 쓰면 읽을 수 없었던 바이트가 U+FFFD로 대체되어 버리기 때문입니다. 이번 Read와 Edit의 결과는 이 설명과 일치했습니다.
Write만 상이했습니다. 같은 설명에는 Write라면 새로운 내용이 U+FFFD를 포함하지 않는 한, 그러한 파일이라도 덮어쓸 수 있다(UTF-8로 저장되며 원래 인코딩은 손실됨)고 적혀 있습니다. 하지만 2.1.322 버전에서는 새로운 내용에 U+FFFD가 포함되지 않음에도 불구하고, 기존 CP932 파일에 대한 Write는 거부되었습니다. 문서와 버전 중 어느 쪽이 차이가 있는지까지는 조사하지 않았습니다.
공식 Issue anthropics/claude-code#7134 (2026-11-11 조사 시점 기준 30개의 반응, open)은 2025년 9월에 Windows-1252 파일로 제기된 것입니다. 본문 내용은 'Read는 올바르게 표시하지만, Edit/Write가 UTF-8로 되돌려 쓰면서 손상시킨다'는 보고였습니다. 이후 댓글에는 Read가 U+FFFD를 반환한다는 보고(2026년 7월)와, 2.1.296에서 Edit이 거부로 변경되었다는 보고(2026년 10월 11일)가 있습니다. 후자의 경우, 해당 버전에서는 Write가 거부되지도 않았다고 보고되었습니다. 이번 Read가 U+FFFD를 반환하고 Edit이 거부되는 결과는 이 댓글들과 동일했습니다. Windows-1252 파일은 시도하지 않았습니다.
해결 방법
일본어 CSV를 스크립트로 읽으려면, 이번 두 파일에서는 encoding="cp932"로 읽을 수 있었습니다. iconv 역시 -f CP932를 사용하면 읽을 수 있었습니다.
성공 (㈱을 포함하여 UTF-8 표준 출력으로 가능)
iconv -f CP932 sales_cp932.csv
실패 (position 32)
...
자동 문자 인코딩 판별에만 의존할 경우, 파일이 짧으면 오류가 발생할 수 있습니다. chardet 5.2.0은 ㈱이 포함된 CP932 파일을 CP932
(확신도 0.99)로 판단했지만, 특수 문자가 없는 짧은 sales_shift_jis_safe.csv는 MacCyrillic
(확신도 0.21, 언어 Russian)으로 판별했습니다. charset_normalizer 3.5.2는 두 경우 모두 일본어 표로 읽을 수 있었습니다. 이 환경에는 file 명령어가 없었습니다.
UTF-8의 BOM(Byte Order Mark)에도 주의할 점이 있습니다. Python의 csv에서 encoding="utf-8"로 sales_utf8sig.csv를 읽으면, 열 이름이 \ufeff상품가 되어 row["商品"]로는 가져올 수 없습니다. encoding="utf-8-sig"를 사용하면 가져올 수 있습니다. 반면, pandas 3.0.6에서는 encoding="utf-8"을 사용해도 BOM이 열 이름에서 제외되었습니다. 같은 'utf-8'이라도 사용하는 라이브러리에 따라 열 이름이 달라집니다. 참고로 이 환경의 iconv에는 UTF-8-SIG라는 별칭은 없었습니다 (conversion from 'UTF-8-SIG' is not supported).
Claude Code에서 내용을 읽거나 수정하고 싶을 때는, Edit/Write를 하기 전에 직접 UTF-8로 변환하는 것이 안전합니다. 변환하면 원래의 CP932는 남아있지 않으므로, 먼저 복사본을 만들어 두는 것을 권장합니다. 인코딩을 유지한 채로 수정하려면, 거부 메시지에 나와 있듯이 iconv처럼 파일의 문자 코드를 지정할 수 있는 명령어를 사용해야 합니다.
확인 방법
- 일본어가 포함된 CSV를 UTF-8로 열 수 있는지 먼저 시도해 봅니다.
UnicodeDecodeError가 발생하면 CP932를 의심합니다.
encoding="cp932"와 encoding="shift_jis" 모두를 테스트하여, ㈱과 같은 확장 문자로 차이가 발생하는지 확인합니다.
- Claude Code의 Read에 전달해 보고, U+FFFD 및 'not valid UTF-8' 경고 메시지가 나오는지 확인합니다.
- 편집할 경우, 복사본을 만든 후 UTF-8로 변환한 다음에 Edit를 수행합니다.
환경이나 버전에 따라 결과가 달라질 수 있으므로, 본인의 CSV 파일로도 한 번 시도해 보는 것이 좋습니다.
참고
- Tools reference (Claude Code 공식)
- anthropics/claude-code#7134 (비 UTF-8 파일의 문자 코드 유지 요청)
토론