테마 전환

Cursor 버그 수정 완벽 가이드: 오류 분석부터 해결책 검증까지 효율적인 워크플로

Easton editorial illustration: service topology model

콘솔이 또 눈이 따가울 만큼 새빨갛습니다.

화면에는 TypeError: Cannot read property 'map' of undefined가 떠 있습니다. 오늘 밤에만 벌써 세 번째로 보는 오류입니다. 오류 메시지를 복사하고 새 탭을 열어 Google에서 검색하고 Stack Overflow를 뒤지는 이 과정은 눈을 감고도 할 수 있을 정도입니다. 하지만 30분이 지나도록 대여섯 가지 방법을 시도했는데도 문제는 그대로였습니다.

그 후 Cursor를 쓰기 시작했을 때는 구세주를 찾았다고 생각했습니다. 이제 AI가 버그 수정을 도와줄 수 있으니까요. 그러나 실제로는 전혀 그렇지 않았습니다. 오류 메시지를 AI에게 바로 던지면 엉뚱한 해결책을 내놓거나, 하나를 고치는 대신 다른 곳을 망가뜨리곤 했습니다.

완전한 Cursor 디버깅 워크플로를 직접 정립하고 나서야 문제는 도구가 아니라 저에게 있었다는 사실을 알았습니다. 도구가 나쁜 것이 아니라 제가 사용할 줄 몰랐던 것입니다.

이 글에서는 여러 시행착오 끝에 정리한 이 워크플로의 핵심 4단계를 공유합니다. ‘오류가 났는데 AI에게 어떻게 도움을 받아야 할지 모르겠다’는 곤란을 겪어 봤다면 이 경험이 도움이 되기를 바랍니다.

1단계: 오류 정보를 올바르게 수집하고 분석하기

예전에는 꽤 어리석은 실수를 했습니다. 오류를 보면 첫 줄만 복사해서 Cursor에 던졌습니다.

예를 들어 Error: Cannot find module 'express'가 보이면 곧바로 “Cursor, 이 오류를 고쳐 줘”라고 물었습니다. AI는 영문을 모르겠다는 듯 전혀 맞지 않는 해결책을 내놓았습니다. 나중에야 전체 스택 트레이스가 핵심이라는 사실을 깨달았습니다.

첫 줄만 보지 말고 전체 스택 트레이스를 확인하세요

오류 메시지는 의사의 진료와 비슷합니다. 증상(첫 줄)은 표면에 드러난 현상일 뿐이고, 병의 원인은 뒤에 나오는 검사 보고서(스택)에 숨어 있습니다.

전체 오류 스택 트레이스는 다음과 같습니다.

TypeError: Cannot read property 'map' of undefined
    at UserList.render (src/components/UserList.jsx:23:18)
    at finishClassComponent (react-dom.development.js:17485:31)
    at updateClassComponent (react-dom.development.js:17435:24)

첫 줄은 ‘무슨 문제가 생겼는지’를, 뒤의 몇 줄은 ‘어디에서 문제가 생겼는지’를 알려 줍니다. 위 내용을 보면 문제는 React 소스 코드가 아니라 UserList.jsx의 23번째 줄에서 발생했습니다. 이 정보는 매우 중요합니다.

제 습관: 오류를 만나면 첫 줄만 복사하지 않고 먼저 전체 스택 정보(보통 5~10줄)를 가져옵니다.

오류 유형을 구분하고 전부 한데 섞지 마세요

오류 유형에 따라 처리 방법도 달라집니다. 저는 대체로 다음과 같이 분류합니다.

  1. 구문 오류: 괄호가 하나 빠졌거나 키워드 철자가 틀린 경우입니다. Cursor가 한눈에 알아볼 수 있습니다.
  2. 런타임 오류: undefined is not a function 같은 오류로, 보통 데이터나 로직에 문제가 있습니다.
  3. 타입 오류(TypeScript): 타입이 일치하지 않는 경우입니다. 관련 타입 정의도 AI에게 함께 보여 줘야 합니다.
  4. 의존성/환경 오류: Module not found 같은 오류는 package.json과 Node 버전을 확인해야 합니다.

Cursor에 질문할 때는 “이 오류는 TypeScript 타입 오류입니다”와 같이 오류 유형을 먼저 설명합니다. 그러면 AI도 어느 방향으로 생각해야 하는지 알 수 있습니다.

어떤 작업 후 오류가 발생했는지 컨텍스트를 기록하세요

한번은 설정 파일 하나를 바꿨더니 프로젝트 전체가 실행되지 않았습니다. 저는 오류 메시지만 Cursor에 주었고 Cursor는 코드 수정을 권했습니다. 한참을 고쳐도 아무 소용이 없었습니다.

나중에 “방금 webpack.config.js의 entry를 바꿨습니다”라고 덧붙이자 Cursor는 경로가 잘못됐다는 사실을 바로 알아차렸습니다.

교훈: 방금 어떤 작업을 했는지 AI에게 알려 주세요. 그 작업은 ‘문제가 없을 것’이라고 생각하더라도 말해야 합니다. 문제는 종종 ‘문제없어야 할’ 곳에서 생깁니다.

지금은 다음 내용을 기록하는 습관이 있습니다.

  • 수정한 파일
  • 새로 설치한 의존성
  • 전환한 환경(예: Node 버전)

길게 쓸 필요 없이 한두 문장이면 충분합니다. 그러나 이 정보가 있으면 AI가 문제의 범위를 빠르게 좁힐 수 있습니다.

2단계: Cursor에 정확한 컨텍스트 제공하기

Cursor를 처음 쓸 때는 AI가 모든 것을 알고 있으니 아무렇게나 물어도 된다는 큰 오해를 했습니다.

하지만 AI는 프로젝트가 어떤 기술 스택을 쓰는지, 의존성 버전이 무엇인지, 설정 파일이 어떻게 생겼는지 전혀 모릅니다. 알려 주지 않으면 추측할 수밖에 없습니다. 그리고 추측의 결과는 프로젝트에 전혀 맞지 않는 해결책이었습니다.

나중에 너무 많지도 적지도 않게 정확한 컨텍스트를 제공하는 요령을 익혔습니다.

@ 기호로 관련 파일 참조하기

Cursor에는 @파일명으로 파일 내용을 직접 참조하는 매우 유용한 기능이 있습니다.

예를 들어 컴포넌트에서 오류가 발생하면 다음과 같이 질문합니다.

@UserList.jsx 이 컴포넌트에서 오류가 발생했습니다. 오류 정보는 다음과 같습니다.
[전체 스택 붙여넣기]

이렇게 하면 Cursor가 설명만으로 추측하지 않고 컴포넌트 코드 전체를 볼 수 있습니다.

주의 사항: 한 번에 너무 많은 파일을 참조하지 마세요. 한꺼번에 78개 파일을 @로 넣어 봤더니 AI가 오히려 핵심을 잡지 못했습니다. 일반적으로 관련 파일 23개면 충분합니다.

디렉터리 전체에 문제가 있다면 @folder/를 사용할 수 있습니다. 다만 솔직히 그런 경우는 드물고, 대부분의 문제는 몇 개 파일에 집중되어 있습니다.

관련 설정 파일 보여 주기

코드 문제처럼 보이지만 실제로는 설정 문제인 오류도 있습니다.

예를 들어 TypeScript 타입 오류는 tsconfig.json 설정이 잘못돼서 생길 수 있습니다. 의존성을 찾지 못한다면 package.json의 버전 충돌이 원인일 수 있습니다.

제 경험상 다음 유형의 오류를 만나면 설정 파일을 AI에게 직접 보여 주는 편이 좋습니다.

  • 타입 오류@tsconfig.json
  • 컴파일 오류@webpack.config.js 또는 @vite.config.js
  • 의존성 오류@package.json
  • 환경 문제 → Node 버전과 운영체제를 AI에게 알리기

한번은 코드에는 아무 문제가 없는데 컴파일만 되지 않는 아주 이상한 일을 겪었습니다. 한 시간 동안 애를 먹다가 package.json을 Cursor에 보여 주자 React와 React-DOM 버전이 일치하지 않는다는 사실을 바로 찾아냈습니다.

그 순간 정말 모든 것이 명확해졌습니다. 설정 파일을 더 일찍 보여 줬다면 한 시간을 아낄 수 있었을 것입니다.

필요한 타입 정의 제공하기

TypeScript를 사용한다면 이 부분이 특히 중요합니다.

AI는 사용자가 정의한 타입의 구조를 알지 못합니다. User 타입에서 오류가 났다고 해도 User에 어떤 필드가 있는지 모릅니다.

해결 방법: 타입 정의를 함께 보여 주세요.

@types/user.ts로 직접 참조하거나 관련 interface를 복사해 올 수 있습니다.

interface User {
  id: string;
  name: string;
  email: string;
}

// 여기에서 오류 발생: Type 'undefined' is not assignable to type 'string'
const user: User = getUserData();

그러면 AI가 기대하는 데이터 구조를 파악해 더 정확한 수정안을 제시할 수 있습니다.

고급 팁: 오류가 서드파티 라이브러리의 타입(예: node_modules의 타입 선언)과 관련 있다면 AI에게 해당 라이브러리의 타입 정의를 확인하라고 요청할 수 있습니다. 하지만 이런 경우는 드물며, 대체로 AI도 자주 쓰이는 라이브러리의 타입을 기본적으로 이해합니다.

3단계: Cursor가 신뢰할 수 있는 해결책을 만들도록 유도하기

오류 정보를 수집하고 컨텍스트까지 제공했다면 이제 Cursor에게 해결책을 받을 차례입니다.

그러나 여기에도 함정이 있습니다. 많은 사람이 “수정해 줘”라고 바로 말하고 AI는 곧바로 코드를 바꿉니다. 왜 그렇게 바꿨는지 이해하지 못하면 다음에 비슷한 문제를 만나도 해결할 수 없습니다.

지금은 AI에게 먼저 설명하게 한 다음 코드를 수정하게 합니다.

구조화된 방식으로 질문하기

다음 두 가지 질문 방식을 비교해 보세요.

❌ 비효율적인 질문:

여기에서 오류가 나요. 수정해 주세요.
[오류 정보 붙여넣기]

✅ 효율적인 질문:

사용자 목록 기능을 구현하는 중 타입 오류가 발생했습니다.

배경: API에서 사용자 데이터를 가져온 뒤 목록으로 렌더링
오류 정보: TypeError: Cannot read property 'map' of undefined
기대 결과: 사용자 목록 정상 표시

@UserList.jsx
@api/users.ts

차이가 보이나요? 두 번째 질문은 다음 내용을 명확히 설명합니다.

  1. 무엇을 하고 있는지(구현하려는 기능)
  2. 어떤 문제가 생겼는지(오류 정보)
  3. 어떤 결과를 기대하는지
  4. 관련 코드가 어디에 있는지

이렇게 하면 AI가 전체 사고의 틀을 확보하므로 훨씬 신뢰할 수 있는 해결책을 내놓습니다.

Cursor의 여러 기능 활용하기

Cursor에는 채팅만 있는 것이 아닙니다. 상황에 따라 사용할 수 있는 기능이 여러 가지입니다.

1. Cmd/Ctrl + K(인라인 편집)
코드 몇 줄을 수정할 때 적합합니다. 오류가 난 줄을 선택하고 단축키를 누른 뒤 AI에게 원하는 변경을 설명하세요.

저는 타입 표기나 매개변수 조정처럼 명확한 작은 문제를 빠르게 수정할 때 자주 사용합니다.

2. Chat(채팅 창)
여러 차례 대화가 필요한 복잡한 문제에 적합합니다.

문제가 어디에서 생겼는지 모를 때는 먼저 “이 오류가 발생할 수 있는 원인은 무엇인가요?”라고 묻습니다. AI가 몇 가지 방향을 제시하면 분석 내용에 따라 계속 질문합니다.

3. Composer(여러 파일 협업)
여러 파일에 걸친 문제를 수정할 때 적합합니다.

예를 들어 API 인터페이스를 바꾸면 컴포넌트, 타입 정의, 테스트 파일도 함께 수정해야 합니다. Composer를 사용하면 연관된 여러 파일을 한 번에 처리할 수 있습니다.

알맞은 도구 선택은 중요합니다. 예전에는 모든 문제에 Chat을 썼기 때문에 간단한 문제는 복잡해지고, 복잡한 문제는 제대로 설명하기 어려웠습니다. 지금은 문제 유형에 따라 기능을 골라 훨씬 효율적으로 작업합니다.

‘어떻게’보다 ‘왜’를 먼저 물으세요

제가 가장 중요하다고 생각하는 부분입니다.

AI에게 코드를 바로 고치라고 하기보다 먼저 설명하게 하세요.

첫 번째 대화:

이 오류가 발생할 수 있는 원인은 무엇인가요? 어떤 가능성이 있나요?

AI는 다음과 같은 원인을 분석해 줍니다.

  • 데이터 로딩이 끝나기 전에 렌더링했을 수 있음
  • API의 응답 형식이 잘못됐을 수 있음
  • 컴포넌트 상태 초기화에 문제가 있을 수 있음

두 번째 대화:

어떤 해결책이 있나요? 각각 어떤 장단점이 있나요?

AI가 여러 해결책을 제시하면 프로젝트 상황에 가장 잘 맞는 것을 선택할 수 있습니다.

세 번째 대화:

두 번째 해결책을 사용하고 싶습니다. 구현해 주세요.

이렇게 하면 다음과 같은 이점이 있습니다.

  1. 문제의 근본 원인을 이해합니다.
  2. 선택할 수 있는 해결책이 여러 가지임을 알게 됩니다.
  3. AI의 첫 번째 제안을 수동적으로 받아들이지 않고 직접 선택합니다.

한번은 성능 문제가 발생했을 때 AI가 처음에는 useMemo를 쓰라고 제안했습니다. 다른 해결책을 묻자 데이터 구조를 최적화하거나 렌더링 로직을 바꿀 수도 있다고 답했습니다. 저는 데이터 구조 최적화를 선택했고, useMemo를 추가하는 것보다 훨씬 근본적으로 문제를 해결했습니다.

AI에게 바로 수정하게 했다면 증상만 완화할 뿐 근본 원인을 해결하지 못하는 useMemo 방식을 그대로 받아들였을지도 모릅니다.

4단계: AI 수정안 검증 및 테스트하기

AI가 해결책을 제시하고 코드도 바꿨다면 이제 문제가 해결된 것일까요?

아직 축하하기는 이릅니다.

저는 AI의 변경을 완전히 믿고 제대로 살펴보지도 않은 채 커밋했다가 큰 문제를 겪었습니다. 배포 후 A 문제는 해결됐지만 B 문제가 새로 생겼고, 롤백하느라 진땀을 뺐습니다.

그때부터 AI의 변경은 한 단계도 빠짐없이 반드시 검증해야 한다는 습관이 생겼습니다.

코드 변경을 꼼꼼하게 리뷰하세요

AI가 코드를 수정하면 가장 먼저 Git에서 diff를 확인합니다.

git diff

다음 내용을 한 줄씩 확인합니다.

  • 이 줄에서 무엇을 바꿨는가?
  • 왜 이렇게 바꿨는가?
  • 다른 기능에 영향을 주지 않는가?

한번은 AI가 타입 오류를 수정하면서 함수의 매개변수 타입을 string에서 string | undefined로 바꿨습니다. 보기에는 문제가 없어 보였지만 이 함수는 다른 십여 곳에서 호출되고 있었고, 그 어떤 곳도 undefined를 처리하지 않았습니다.

diff를 꼼꼼히 확인하지 않았다면 시한폭탄이 됐을 것입니다.

제 원칙: 모든 변경의 의도를 이해합니다. 이해되지 않는 부분이 있으면 “왜 이렇게 바꿨나요? 부작용은 없나요?”라고 AI에게 묻습니다.

디버그 로그를 추가해 접근 방식을 검증하세요

코드를 바꿔서 겉으로 오류가 사라졌지만 실제로 수정된 것인지, 오류를 숨기기만 한 것인지 확신할 수 없을 때가 있습니다.

이럴 때는 핵심 단계에 console.log를 추가해 검증합니다.

// AI가 수정한 위치에 로그 추가
console.log('사용자 데이터:', users);
console.log('데이터 타입:', Array.isArray(users));

return users.map(user => <UserItem key={user.id} {...user} />);

그런 다음 Cursor에게 로그 출력을 보여 줍니다.

로그를 추가했더니 다음과 같이 출력됩니다.
사용자 데이터: undefined
데이터 타입: false

아직 데이터를 불러오지 못한 것 같은데 수정 방향이 잘못된 것 아닐까요?

AI가 로그를 바탕으로 다시 분석하면 문제가 렌더링 로직이 아니라 데이터 가져오기 계층에 있다는 사실을 발견할 수 있습니다.

이 방법은 특히 유용합니다. 문제가 A에 있다고 생각했는데 실제로는 B에 있는 경우가 많습니다. 로그를 사용하면 진짜 문제가 있는 곳을 빠르게 찾을 수 있습니다.

테스트 실행하기

프로젝트에 단위 테스트가 있다면 수정 후 반드시 실행하세요.

npm test

많은 프로젝트에 완전한 테스트가 없다는 점은 저도 잘 압니다. 예전 제 프로젝트도 그랬습니다. 하지만 테스트가 있다면 반드시 활용해야 합니다. 테스트는 사용자와 AI 모두 생각하지 못한 경계 조건을 찾아 줍니다.

한번은 AI가 배열 처리 버그를 고쳐 줬고 변경 내용에도 문제가 없어 보였습니다. 그러나 테스트를 실행하자 배열이 비어 있을 때 오류가 발생했습니다. AI가 정상적인 상황만 고려하고 빈 배열을 생각하지 않은 것입니다.

직접 테스트하는 것도 중요합니다.

  • 수정 전에 오류가 발생했던 상황 테스트(문제 해결 확인)
  • 정상 흐름 테스트(기존 기능이 손상되지 않았는지 확인)
  • 경계 조건 테스트(null, 극단적인 입력 등)

저는 보통 간단한 테스트 체크리스트를 만듭니다.

  • 원래 오류가 발생한 상황이 수정됐는가?
  • 정상 데이터를 올바르게 처리하는가?
  • 빈 데이터/비정상 데이터를 올바르게 처리하는가?
  • 이 함수를 호출하는 다른 곳도 정상적으로 작동하는가?

실제 사례: AI 수정으로 발생한 부작용

실제로 겪은 사례를 하나 소개하겠습니다.

React 컴포넌트가 반복 렌더링되는 문제가 생겼을 때 AI는 함수를 useCallback으로 감싸라고 제안했습니다. 수정 후에는 실제로 반복 렌더링이 멈췄습니다.

그러나 페이지 로딩 속도가 느려졌습니다. 자세히 살펴보니 AI가 추가한 useCallback 의존성에 객체가 포함되어 있었고, 이 객체가 매번 새로 생성되면서 useCallback이 전혀 효과를 내지 못하고 추가 오버헤드만 만들고 있었습니다.

제가 AI에게 “이 의존성에 문제가 있지 않나요?”라고 다시 물은 뒤에야 AI도 문제를 알아차리고 객체를 useMemo로 캐시하거나 기본 타입을 전달하라고 제안했습니다.

교훈: AI의 해결책이 반드시 최선은 아니며, 새로운 문제를 만들 수도 있습니다. 동료의 코드를 검토하듯 AI의 변경도 검토해야 합니다.

맹신하지도, 지나치게 의심하지도 마세요

검증 단계를 이렇게 많이 이야기하면 너무 번거롭다고 느낄 수도 있습니다.

물론 검증에는 시간이 듭니다. 하지만 운영 환경에서 문제가 발생한 뒤 긴급 롤백하는 것과 비교하면 충분히 투자할 가치가 있습니다.

그리고 검증을 반복하다 보면 AI가 자주 저지르는 문제의 패턴도 보입니다. 예를 들어 null/undefined 처리를 빠뜨리는 일이 잦다면 미리 대비할 수 있습니다.

균형점: 간단한 변경은 빠르게 검증하고 복잡한 변경은 꼼꼼하게 테스트하세요. 변경의 영향 범위에 맞춰 검증 강도를 결정하면 됩니다.

실전 사례: 완전한 버그 수정 과정

이론은 충분히 살펴봤으니 실제 사례를 보겠습니다.

지난주 Next.js 프로젝트에서 갑자기 컴파일 오류가 발생했습니다. 페이지 전체가 하얗게 변하고 콘솔은 온통 빨간색이었습니다.

상황 설명

오류 정보는 다음과 같았습니다.

Error: Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: undefined.

Check the render method of `BlogPost`.
    at createFiberFromTypeAndProps (react-dom.development.js:25532:21)
    at createFiberFromElement (react-dom.development.js:25560:15)

당시 제 첫 반응은 이랬습니다. 뭐라고요? undefined라니요? 분명 컴포넌트를 가져왔는데 말입니다.

Step 1: 오류 정보 전체 수집

첫 줄만 복사하지 않고 전체 스택 트레이스 약 10줄을 모두 복사했습니다. 핵심 정보는 두 번째 줄에 있었습니다. BlogPost 컴포넌트의 render 메서드에서 문제가 발생한 것입니다.

컨텍스트도 기록했습니다.

  • 새 의존성 react-markdown을 방금 설치함
  • BlogPost.tsx의 import 문을 수정함

Step 2: 정확한 컨텍스트 제공

Cursor Chat을 열고 다음과 같이 질문했습니다.

Next.js 프로젝트에서 컴포넌트 import 오류가 발생했습니다.

배경: react-markdown(v9.0.1)을 방금 설치하고 BlogPost 컴포넌트에서 import해 사용함
오류 정보: [전체 스택 붙여넣기]
기대 결과: Markdown 콘텐츠 정상 렌더링

@components/BlogPost.tsx
@package.json

이제 Cursor는 다음 내용을 확인할 수 있습니다.

  1. 사용 중인 react-markdown 버전
  2. BlogPost 컴포넌트의 전체 코드
  3. 프로젝트의 의존성 상태

Step 3: 여러 차례 대화로 해결책 찾기

첫 번째 대화에서 먼저 물었습니다.

이 오류의 원인은 무엇일까요?

AI는 세 가지 가능성을 제시했습니다.

  1. import 문이 잘못됨(named import와 default import)
  2. react-markdown 버전과 React 버전이 호환되지 않음
  3. 컴포넌트 설치가 완료되기 전에 사용함

두 번째 대화에서는 다음과 같이 말했습니다.

의존성은 이미 설치된 것을 확인했습니다. import 문이 문제일 수 있을까요?
현재 코드는 다음과 같습니다: import { ReactMarkdown } from 'react-markdown'

AI는 문제를 바로 찾아냈습니다.

react-markdown v9은 named export가 아니라 default export를 사용합니다.
다음과 같이 바꿔야 합니다: import ReactMarkdown from 'react-markdown'

Step 4: 수정 내용 검증

AI의 제안대로 import 문을 바꿨지만 바로 믿지는 않았습니다.

먼저 Git diff를 확인했습니다.

- import { ReactMarkdown } from 'react-markdown'
+ import ReactMarkdown from 'react-markdown'

변경이 아주 작아 부작용은 없을 듯했습니다.

그런 다음 프로젝트를 실행했습니다.

npm run dev

페이지가 정상적으로 표시됐습니다.

그래도 몇 가지 상황을 추가로 테스트했습니다.

  • 일반 Markdown 콘텐츠 렌더링
  • 코드 블록이 있는 Markdown
  • 콘텐츠가 비어 있는 경우

모두 문제가 없었습니다. 그제야 문제가 실제로 해결됐다고 확인했습니다.

소요 시간 비교

기존 방식:

  • Google에서 “react-markdown undefined error” 검색 → 10분
  • Stack Overflow의 여러 답변에서 세 가지 해결책을 시도했지만 모두 실패 → 20분
  • react-markdown 공식 문서 확인 → 15분
  • 합계: 45분

Cursor 보조 방식:

  • 오류 정보와 컨텍스트 수집 → 2분
  • 여러 차례 대화로 문제 파악 → 3분
  • 수정안 검증 → 2분
  • 합계: 7분

효율이 6배 이상 향상됐습니다.

핵심은 Cursor에 버전 번호, 코드, 오류 정보 등 충분한 컨텍스트를 제공했다는 점입니다. 덕분에 제가 해결책을 하나씩 직접 시도하지 않아도 Cursor가 문제의 근본 원인을 바로 찾을 수 있었습니다.

결론

이 Cursor 디버깅 워크플로를 다시 정리해 보겠습니다.

  1. 오류를 빠짐없이 수집하세요: 첫 줄만 보지 마세요. 전체 스택 트레이스에 가치 있는 정보가 있습니다.
  2. 정확한 컨텍스트를 제공하세요: @로 파일을 참조하고 설정과 타입 정의를 제공하세요.
  3. 해결책을 합리적으로 선택하세요: 왜 그런지 먼저 물은 뒤 방법을 묻고, 수동적으로 받아들이지 말고 직접 선택하세요.
  4. 철저하게 검증하고 테스트하세요: 코드 리뷰, 로그 추가, 테스트 실행 중 하나도 빼놓으면 안 됩니다.

단계가 많아 보이지만 익숙해지면 전체 과정에 몇 분밖에 걸리지 않습니다. 기존의 Google + Stack Overflow + 시행착오 반복보다 훨씬 효율적입니다.

다만 한 가지는 분명히 해야 합니다. Cursor는 도구이지 마법이 아닙니다.

Cursor가 사용자를 대신해 생각하거나 코드 로직을 이해해 줄 수는 없습니다. 문제를 빠르게 찾고 제안을 제공하는 매우 똑똑한 조수일 뿐입니다. 최종 결정은 여전히 사용자의 몫입니다.

지금 제게 Cursor 디버깅은 경험 많은 동료가 옆에 앉아 있는 것과 비슷합니다. 문제가 생기면 언제든 “이게 무슨 상황이죠?”라고 물을 수 있고, 동료는 몇 가지 원인을 분석해 줍니다. 그러면 실제 상황에 맞춰 직접 판단하면 됩니다.

혼자 문서에 파묻히는 것보다 훨씬 수월합니다.

마지막 제안: 자신만의 디버깅 체크리스트를 만드세요.

저는 오류를 만나면 다음 체크리스트를 따릅니다.

  • 전체 오류 스택 트레이스 복사
  • 방금 수행한 작업 기록
  • @로 관련 파일 2~3개 참조
  • 설정/타입과 관련 있다면 함께 제공
  • AI에게 먼저 원인을 분석하게 한 뒤 해결책 선택
  • 코드 변경 리뷰
  • 원래 오류가 발생한 상황 + 경계 조건 테스트

이 습관을 들이면 디버깅 효율이 비약적으로 향상됩니다.

직접 시도해 보세요. 골치 아픈 오류도 빠르게 해결할 수 있습니다.

Cursor AI 보조 디버깅 전체 과정

오류 수집부터 검증과 테스트까지 Cursor로 버그를 효율적으로 수정하는 4단계 체계적 방법

⏱️ Estimated time: 10 min

  1. 1

    Step 1: 1단계: 오류 정보 전체 수집

    핵심 원칙: 첫 줄보다 전체 스택 트레이스가 중요합니다.

    필수 작업:
    • 오류 메시지 첫 줄만이 아니라 전체 스택 트레이스(5~10줄)를 복사합니다.
    • 오류 유형을 구분합니다: 구문 오류/런타임 오류/타입 오류/의존성 오류
    • 작업 컨텍스트를 기록합니다: 방금 수정한 파일, 설치한 의존성, 전환한 환경

    이렇게 해야 하는 이유:
    스택 정보에는 오류가 발생한 정확한 위치(파일명+줄 번호)가 들어 있습니다. 첫 줄은 ‘무슨 문제가 생겼는지’만 알려 주고, 뒤의 몇 줄이 ‘어디에서 문제가 생겼는지’를 알려 줍니다. 작업 컨텍스트를 제공하면 AI가 조사 범위를 빠르게 좁힐 수 있습니다.

    주의 사항:
    어떤 작업이 ‘문제없을 것’이라고 생각해도 빼놓지 마세요. 많은 버그가 바로 ‘문제없다’고 여긴 곳에 숨어 있습니다.
  2. 2

    Step 2: 2단계: 정확한 컨텍스트 제공

    핵심 원칙: AI가 이해하는 데 딱 필요한 만큼만 제공합니다.

    필수 작업:
    • @ 기호로 관련 파일 2~3개를 참조하고 한 번에 너무 많은 파일을 넣지 않습니다.
    • 오류 유형에 따라 설정 파일을 제공합니다:
    - 타입 오류 → @tsconfig.json
    - 컴파일 오류 → @webpack.config.js 또는 @vite.config.js
    - 의존성 오류 → @package.json
    • TypeScript 프로젝트라면 관련 interface/type 정의를 제공합니다.

    이렇게 해야 하는 이유:
    AI는 프로젝트의 기술 스택, 의존성 버전, 사용자 정의 타입을 알지 못합니다. 정확한 컨텍스트를 주면 일반론이 아니라 해당 프로젝트에 맞는 해결책을 제시할 수 있습니다.

    주의 사항:
    참조 파일은 2~3개로 제한하세요. 너무 많으면 AI의 판단을 방해할 수 있습니다. 어떤 파일이 관련 있는지 모르겠다면 먼저 AI에게 어떤 파일이 필요한지 물어보세요.
  3. 3

    Step 3: 3단계: AI가 신뢰할 수 있는 해결책을 만들도록 유도

    핵심 원칙: 방법을 묻기 전에 이유부터 묻습니다.

    필수 작업:
    • 첫 번째 대화: ‘이 오류가 발생할 수 있는 원인은 무엇인가요?’라고 묻습니다.
    • 두 번째 대화: ‘어떤 해결책이 있으며 각각의 장단점은 무엇인가요?’라고 묻습니다.
    • 세 번째 대화: 가장 적합한 해결책을 선택하고 AI에게 구현을 요청합니다.
    • 알맞은 도구를 선택합니다:
    - Cmd/Ctrl+K: 한 파일의 작은 변경
    - Chat: 복잡한 문제를 다루는 여러 차례의 대화
    - Composer: 여러 파일을 함께 수정

    이렇게 해야 하는 이유:
    AI에게 바로 코드 수정을 맡기면 원리를 이해하지 못해 다음에도 같은 문제를 해결하지 못합니다. 여러 차례 대화하면 문제의 근본 원인을 이해하고 첫 번째 제안을 수동적으로 받아들이는 대신 최적의 해결책을 직접 선택할 수 있습니다.

    주의 사항:
    AI의 첫 반응이 최적의 답은 아닐 수 있습니다. 예를 들어 성능 문제에 useMemo를 제안할 수 있지만, 데이터 구조를 최적화하는 편이 더 근본적인 해결책일 수 있습니다.
  4. 4

    Step 4: 4단계: 철저한 검증과 테스트

    핵심 원칙: 동료의 코드를 검토하듯 AI의 변경 사항을 검토합니다.

    필수 작업:
    • git diff로 변경 내용을 한 줄씩 리뷰하고 각 변경의 의도를 이해합니다.
    • 핵심 단계에 console.log를 추가해 수정 방향이 맞는지 확인합니다.
    • 테스트가 있다면 npm test를 실행합니다.
    • 다음 세 가지 상황을 직접 테스트합니다:
    - 원래 오류가 발생한 상황(문제가 해결됐는지 확인)
    - 정상 흐름(기존 기능이 손상되지 않았는지 확인)
    - 경계 조건(null, 비정상 입력 등)

    이렇게 해야 하는 이유:
    AI가 A 문제를 해결하면서 B 문제를 새로 만들 수 있습니다. 예를 들어 함수 매개변수 타입을 바꾸면서 다른 호출부의 호환성을 고려하지 않을 수 있습니다. 철저히 검증하면 배포 후 롤백하는 곤란한 상황을 피할 수 있습니다.

    주의 사항:
    간단한 변경은 빠르게 검증해도 되지만 복잡한 변경은 반드시 꼼꼼하게 테스트하세요. 검증에 드는 시간은 운영 환경에서 문제가 난 뒤 수정하는 시간보다 훨씬 짧습니다.

FAQ

왜 오류의 첫 줄만 Cursor에 복사하면 안 되나요?
오류 메시지 첫 줄은 TypeError처럼 ‘무슨 문제가 생겼는지’만 알려 주지만, 전체 스택 트레이스가 있어야 ‘어디에서 문제가 생겼는지’를 알 수 있습니다.

예시:
첫 줄: TypeError: Cannot read property 'map' of undefined
스택 정보: at UserList.render (src/components/UserList.jsx:23:18)

첫 줄은 타입 오류라는 사실만 알려 주지만, 스택은 UserList.jsx의 23번째 줄에서 문제가 발생했다고 알려 줍니다. 스택 정보가 없으면 AI는 추측할 수밖에 없어 제안의 신뢰도가 떨어집니다.

올바른 방법: 전체 스택 트레이스(5~10줄)를 복사해 AI가 문제의 근원을 정확하게 찾도록 하세요.
Cursor에 어떤 설정 파일을 보여 줘야 하는지 어떻게 판단하나요?
오류 유형에 따라 결정하세요.

타입 오류(TypeScript) → @tsconfig.json + 관련 타입 정의 파일
컴파일 오류 → @webpack.config.js 또는 @vite.config.js
의존성 오류(Module not found) → @package.json
환경 문제 → Node 버전과 운영체제를 AI에게 알립니다.

빠른 판단 요령:
오류 메시지에 ‘compilation failed’처럼 설정 관련 내용이 나오면 컴파일 설정을 제공하세요. 모듈을 찾을 수 없다고 나오면 package.json을, 타입이 일치하지 않는다면 tsconfig와 타입 정의를 제공하세요.

한 번에 너무 많은 파일(3개 초과)을 참조하면 AI의 판단을 방해할 수 있으니 피하세요.
Cursor의 Chat, Cmd+K, Composer 중 무엇을 선택해야 하나요?
문제의 복잡도와 관련 파일 수에 따라 선택하세요.

Cmd/Ctrl+K(인라인 편집):
• 한 파일에서 코드 몇 줄만 바꾸는 작은 변경에 적합합니다.
• 타입 표기, 매개변수 조정, 변수 이름 변경 등이 이에 해당합니다.
• 장점: 빠르고 직접적이며 변경 결과를 즉시 볼 수 있습니다.

Chat(채팅 창):
• 여러 차례 대화하며 분석해야 하는 복잡한 문제에 적합합니다.
• 문제의 원인을 모를 때 AI에게 먼저 분석을 요청한 뒤 해결책을 받는 경우 등이 해당합니다.
• 장점: 깊이 있게 논의하며 문제의 본질을 이해할 수 있습니다.

Composer(여러 파일 협업):
• 여러 파일에 걸친 연관 변경에 적합합니다.
• API 인터페이스를 바꾸면서 컴포넌트, 타입, 테스트도 모두 수정해야 하는 경우 등이 해당합니다.
• 장점: 여러 파일을 한 번에 처리하면서 코드의 일관성을 유지합니다.

도구를 잘못 고르면 간단한 문제를 Chat에서 오히려 설명하기 어려워지거나, 복잡한 문제를 Cmd+K로 여러 번 수정해도 해결하지 못할 수 있습니다.
AI의 수정안이 실제로 문제를 해결했는지 어떻게 검증하나요?
다음 세 단계는 하나도 빼놓으면 안 됩니다.

1. 코드 변경 리뷰(git diff):
• 무엇을 왜 바꿨는지 한 줄씩 확인합니다.
• 다른 기능에 영향을 줄 가능성을 생각합니다.
• 이해되지 않는 변경은 즉시 AI에게 물어봅니다.

2. 디버그 로그로 접근 방식 검증:
• 핵심 위치에 console.log를 추가합니다.
• 데이터 흐름이 예상과 일치하는지 확인합니다.
• 오류를 감췄을 뿐인지, 수정 방향이 실제로 맞는지 확인합니다.

3. 세 가지 상황 테스트:
• 원래 오류가 발생한 상황(문제가 해결됐는지 확인)
• 정상 흐름(기능이 손상되지 않았는지 확인)
• 경계 조건(null, 비정상 입력)

실제 사례: AI가 타입 오류를 수정하면서 매개변수 타입을 string|undefined로 바꿔 겉보기에는 오류가 사라졌지만, 다른 십여 개 호출부에서 undefined를 처리하지 않아 잠재적인 문제를 만들었습니다. git diff에서 이 문제를 발견해 배포 사고를 피할 수 있었습니다.
Cursor로 디버깅 효율을 정말 6배 높일 수 있나요?
실제 사례를 기준으로 시간을 비교하면 다음과 같습니다.

기존 방식(45분):
• Google에서 오류 메시지 검색 → 10분
• Stack Overflow에서 세 가지 해결책을 시도했지만 모두 실패 → 20분
• 공식 문서에서 해결책 탐색 → 15분

Cursor 보조 방식(7분):
• 오류 정보 전체와 컨텍스트 수집 → 2분
• 여러 차례 대화로 문제의 근본 원인 파악 → 3분
• 수정안 검증 → 2분

효율 차이의 핵심:
기존 방식은 모든 해결책을 하나씩 시도하는 ‘시행착오의 반복’이라 대부분의 시간을 무효한 시도에 씁니다. Cursor 방식은 컨텍스트를 제공해 AI가 문제의 근본 원인을 바로 찾게 하는 ‘정확한 진단’입니다.

주의: 올바른 질문 방법을 익혔다는 전제가 필요합니다. 오류 메시지만 AI에게 던진다면 효율 향상은 제한적이거나 오히려 더 느릴 수 있습니다.

2분 읽기 · 게시일: 2026년 1월 22일 · 수정일: 2026년 9월 4일

댓글

GitHub로 로그인하여 댓글을 남기세요

Easton BlogEaston Blog