npm ci로 의존성이 설치되지 않고 `@discordjs/voice`를 찾을 수 없다는 오류가 발생할 때의 원인과 해결 절차를 정리한다. 디스코드 봇을 디스호스트 같은 호스팅 환경에 배포할 때 자주 마주치는 문제이며, `package.json`과 `package-lock.json` 불일치가 핵심이다.

2026년 1월 27일·6개 메시지

증상

  • 배포 시 자동 스크립트에서 npm ci 실행 도중 다음과 같은 메시지 발생:
    npm ci can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync.
  • npm ci가 실패해 의존성이 설치되지 않고, 이후 애플리케이션 시작 시 Node가 @discordjs/voice 모듈을 찾지 못해 ERR_MODULE_NOT_FOUND 오류 발생.
  • 로그에 Missing: @discordjs/voice@... from lock file 같은 항목이 보임.

원인

  • npm cipackage-lock.json에 명시된 정확한 상태를 재현하기 위해 사용된다. package.json을 변경한 뒤 package-lock.json을 갱신하지 않으면 동기화되지 않아 설치를 중단한다.
  • package.json에 새로 추가한 패키지(@discordjs/voice 등)가 lock 파일에 반영되지 않으면 npm ci는 보안/일관성 이유로 설치를 거부한다.
  • 그 결과 호스팅 환경에서는 의존성이 전혀 설치되지 않아 require/import 시 모듈 없음 오류가 발생한다.

해결 방법

1단계: 호스팅에서 빠르게 동작시키기 (임시/간편)

호스팅의 시작 스크립트에서 npm cinpm install로 변경하면 의존성 설치가 진행되어 즉시 서비스가 작동한다. 단, 재현성(reproducibility)은 떨어진다.

예시 변경 전/후:

# 변경 전 (문제 발생)
if [ -d .git ] && [ "${AUTO_UPDATE}" == "1" ]; then git pull origin ${BRANCH} && npm ci --omit=dev --no-audit --no-fund --foreground-scripts; fi; npm run start

# 변경 후 (임시 해결)
if [ -d .git ] && [ "${AUTO_UPDATE}" == "1" ]; then git pull origin ${BRANCH} && npm install --omit=dev --no-audit --no-fund --foreground-scripts; fi; npm run start
  • 사용 이유: npm installpackage.json 기반으로 lockfile을 갱신하거나 필요한 패키지를 설치한다.
  • 주의: 장기적으로는 lock 파일을 정확히 관리하는 것이 안전하다.

2단계: 올바르게 고치기 (권장)

로컬 개발 환경에서 package-lock.json을 갱신한 뒤 커밋/업로드하여 호스팅 환경에서 npm ci가 정상 동작하도록 만든다.

절차:

  1. 저장소를 로컬로 클론 또는 프로젝트 폴더로 이동
git clone <repo-url>
cd <repo>
  1. 의존성 설치 및 lock 파일 갱신
npm install
# 필요 시: rm -rf node_modules package-lock.json && npm install
  1. 설치 확인
npm ls @discordjs/voice
  1. 변경된 package-lock.json을 커밋하여 원격에 푸시
git add package-lock.json
git commit -m "Update package-lock to include @discordjs/voice"
git push
  1. 호스팅에서 자동 배포가 트리거되면 npm ci가 lock 파일과 동기화된 상태로 의존성을 정확히 설치함.
  • 호스팅 패널에서 Git 접근 권한이 없으면 로컬에서 생성한 package-lock.json을 파일 업로드(또는 패널의 파일 편집기)로 올리면 된다.

추가 팁:

  • 특정 패키지만 설치하려면 로컬에서 npm install @discordjs/voice@버전 --save로 lock을 갱신할 수 있다.
  • 설치 후 애플리케이션이 정상적으로 패키지를 찾는지 npm ls로 확인하고, 호스팅에서 시작 로그 확인.

마무리

npm ci 실패는 대부분 package.jsonpackage-lock.json 불일치에서 발생한다. 빠른 복구는 npm install로 가능하지만, 장기적으로는 로컬에서 lock 파일을 갱신해 커밋/업로드해 호스팅(디스호스트)에 배포하는 방식이 안전하다. 디스코드 봇을 안정적으로 호스팅하려면 lock 파일 관리를 습관화하자.