2026. 7. 18.

npm EJSONPARSE는 설치 오류일까 JSON 문법 오류일까?

npm 명령이 EJSONPARSE로 멈췄다면 캐시나 lockfile을 지우기 전에 오류에 찍힌 package.json 경로와 첫 파싱 위치를 확인해야 한다. 최소 수정부터 재실행까지 안전한 순서를 정리했다.

4 min read
npm EJSONPARSE는 설치 오류일까 JSON 문법 오류일까? 대표 이미지

npm install이나 npm run devnpm ERR! code EJSONPARSE에서 멈추면 패키지를 다시 받을 문제가 먼저 떠오른다. 하지만 이 오류의 첫 번째 대상은 캐시가 아니라 터미널에 찍힌 package.json 파일이다. npm의 package.json 공식 문서package.json이 JavaScript 객체처럼 보이는 문서가 아니라 실제 JSON이어야 한다고 못박는다.

답은 짧다. 오류의 파일 경로와 첫 파싱 위치를 적고, 현재 변경을 보존한 뒤, 그 위치의 JSON 문법만 최소 수정한다. 그다음 독립 파서와 원래 npm 명령을 차례로 통과시킨다. 파싱이 실패한 상태에서는 node_modulespackage-lock.json을 먼저 지우지 않는다.

EJSONPARSE가 package.json의 한 문법 위치를 가리키는 비공식 작업 화면

오류에 찍힌 파일 경로와 첫 위치를 고정한다

같은 컴퓨터에 package.json이 여러 개 있을 수 있다. 모노레포라면 루트와 각 앱 폴더에 따로 존재한다. 따라서 에디터에서 열어 둔 파일을 추측하지 말고, 터미널 메시지에 나온 경로를 먼저 확인한다. npm 11.8.0으로 trailing comma를 재현했을 때는 EJSONPARSE 뒤에 JSON 파싱 위치, 줄과 열, 문제가 된 주변 문자열이 이어졌다. npm 버전에 따라 문구는 달라도 가장 먼저 실패한 위치와 대상 파일을 찾는 순서는 같다.

수정하기 전에 Git이 추적하는 파일이라면 변경 범위를 본다.

git diff -- package.json

이 명령은 package.json의 현재 변경만 보여 준다. AI 코딩 도구가 파일을 바꾼 직후라면 새로 붙은 쉼표, 따옴표, 주석, 충돌 표시를 빠르게 좁힐 수 있다. Git 저장소가 아니거나 아직 추적되지 않은 파일이면 복사본을 하나 남긴다. 목적은 되돌릴 지점을 확보하는 것이지 파일을 통째로 초기화하는 것이 아니다.

현재 파일이 정말 JSON으로 읽히지 않는지 바로 재현한다.

node -e "JSON.parse(require('fs').readFileSync('package.json','utf8')); console.log('package.json OK')"

Node.js의 fs.readFileSync 문서에 나온 파일 읽기와 ECMAScript의 JSON.parse 규칙을 한 줄로 묶은 명령이다. 문법이 틀리면 SyntaxError와 위치가 나오고, 통과하면 package.json OK가 출력된다. 원래 npm 명령보다 좁은 검사라서 설치나 스크립트 실행을 섞지 않고 문법만 볼 수 있다.

JavaScript에서 익숙한 문법도 JSON에서는 막힌다

JSON 인터넷 표준 RFC 8259는 객체의 이름과 문자열, 콜론, 쉼표 위치를 엄격하게 구분한다. 에디터가 JavaScript처럼 색을 칠해 줘도 아래 네 가지는 package.json을 깨뜨린다.

package.json에서 자주 틀리는 JSON 문법과 올바른 수정을 비교한 도식

마지막 항목 뒤 쉼표를 지운다

JavaScript 객체에서는 trailing comma를 자주 쓰지만 JSON 배열과 객체의 마지막 값 뒤에는 쉼표를 둘 수 없다. MDN의 JSON.parse 오류 예시도 trailing comma와 작은따옴표 속성 이름이 SyntaxError를 만드는 사례를 보여 준다.

{
  "scripts": {
    "dev": "next dev"
  }
}

파서가 닫는 중괄호나 대괄호 앞을 가리킨다면 바로 앞 항목 끝의 쉼표부터 비교한다. 여러 쉼표를 한꺼번에 지우지 말고 오류 근처 한 곳만 고친 뒤 다시 파싱한다.

키와 문자열은 큰따옴표로 감싼다

{'name': 'demo'}는 JavaScript 객체처럼 보이지만 유효한 JSON이 아니다. JSON 객체의 이름과 문자열은 "name", "demo"처럼 큰따옴표를 사용한다. 작은따옴표를 전체 파일에서 무작정 치환하면 문자열 안의 문장까지 바뀔 수 있으므로 오류 주변 필드만 수정한다.

주석은 별도 문서로 옮긴다

// 나중에 변경이나 /* 임시 */도 표준 JSON 문법에 없다. 설정 이유는 README, 이슈, 커밋 메시지에 남기고 package.json에는 실제 필드와 값만 둔다. 주석을 제거한 뒤에는 앞뒤 쉼표가 하나 더 남지 않았는지도 확인한다.

Git 충돌 표시는 선택을 끝내고 제거한다

<<<<<<<, =======, >>>>>>>가 보이면 두 버전이 파일 안에 함께 남은 상태다. 필요한 scriptsdependencies 값을 선택한 뒤 세 표시 줄을 모두 제거한다. 충돌 해결 버튼이 헷갈리면 Accept Current와 Incoming을 누르기 전에 볼 기준에서 어느 쪽 변경인지 먼저 구분할 수 있다.

최소 수정 뒤 파서와 원래 명령을 두 번 통과시킨다

첫 오류를 고쳤다고 바로 설치를 다시 시작하지 않는다. JSON 파서는 앞의 문법 오류 때문에 뒤의 오류를 아직 읽지 못했을 수 있다. 같은 파서 명령을 반복해 package.json OK가 나올 때까지 한 위치씩 고친다.

package.json 보존부터 npm 재실행까지 네 단계로 확인하는 체크리스트

파싱이 통과하면 npm이 주요 필드를 읽는지도 확인한다.

npm pkg get name scripts

npm pkg get 공식 문서대로 이 명령은 package.json의 필드를 JSON 형태로 보여 준다. namescripts가 예상한 구조인지 확인한 뒤, 처음 실패했던 명령을 그대로 다시 실행한다.

npm run dev

여기서 EJSONPARSE가 사라지고 개발 서버가 시작되면 복구가 끝났다. Missing script: dev가 새로 나오면 JSON 문법은 해결됐고 scripts.dev가 없는 별도 문제다. 이때는 npm run dev가 missing script로 멈출 때 확인할 항목으로 넘어간다. ERESOLVE가 나오면 Found와 peer 버전을 읽는 의존성 점검 순서가 다음 단계다.

파싱 통과 뒤에는 새 오류만 따로 다룬다

EJSONPARSE가 사라졌는데 npm이 계속 실패할 수 있다. 그때도 캐시 삭제나 --force를 한꺼번에 붙이지 않는다. 새 출력의 첫 오류 코드, 실행한 명령, 현재 폴더를 함께 저장하면 문제를 설치, 스크립트, 의존성, 권한으로 다시 나눌 수 있다.

AI에게 수정을 맡길 때는 범위를 package.json 하나로 제한한다.

아래 EJSONPARSE 로그와 package.json diff만 보고 수정해 줘.
package.json을 유효한 JSON으로 만드는 최소 변경만 제안하고,
node_modules와 package-lock.json은 삭제하지 마.
수정 뒤 실행할 JSON 파싱 명령과 원래 npm 명령을 각각 적어 줘.

이 요청은 AI가 의존성을 업그레이드하거나 설정 전체를 다시 쓰는 일을 막는다. 마지막 확인은 설명이 아니라 터미널 출력이다. package.json OK와 원래 npm 명령의 다음 상태를 둘 다 남기면 같은 오류가 다시 생겼을 때 어느 변경부터 되돌릴지 알 수 있다.

참고 출처

이 글은 AI 코딩과 개발 학습의 일반 정보 제공 목적입니다. 도구, 모델, 커리큘럼, 요금은 버전과 시점에 따라 달라질 수 있으므로 실습이나 도입 전 공식 문서와 최신 릴리스 노트를 확인하세요.

다음으로 읽을 기사

같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.

댓글 0

이 글을 읽은 독자들의 생각을 나눠보세요.

비밀번호(선택)

첫 번째 댓글을 남겨보세요

여러분의 생각이 다른 독자에게 도움이 됩니다.