문제 상황
NotebookLM 업로드 스킬이 사용자가 브라우저 인증 플로우를 성공적으로 완료한 후에도 계속 “Auth required” 에러로 실패했다.
인증은 작동했다. 업로드가 그걸 몰랐을 뿐이다.
flowchart LR
A[사용자 업로드 실행] --> B[Shell 래퍼]
B --> C{인증 파일 확인?}
C -->|"찾을 수 없음"| D["Auth required" 에러]
C -->|"발견"| E[TypeScript 실행]
F[인증 플로우] --> G[TypeScript가 Chrome 프로필 저장]
G -.->|"잘못된 아티팩트 타입"| C
조사 과정
Shell 래퍼(notebook.sh)는 다음과 같이 인증을 확인했다:
AUTH_FILE="$AUTH_DIR/notebook-lm-auth.json"
if [[ ! -f "$AUTH_FILE" ]]; then
echo "Auth required..."
exit 1
fi
하지만 TypeScript 구현(upload.ts)은 완전히 다른 방식을 사용했다:
const AUTH_DIR = join(homedir(), ".config", "moltbot", "notebook-lm-chrome");
const browser = await chromium.launchPersistentContext(AUTH_DIR, {
headless: false,
// ... 브라우저 설정
});
인증 플로우는 쿠키와 세션 데이터가 있는 Chrome 프로필 디렉토리를 저장했다. Shell 스크립트는 존재하지 않는 JSON 파일을 확인했다.
flowchart TD
subgraph "Shell이 기대한 것"
A[notebook-lm-auth.json]
B[{"token": "...", "expiry": "..."}]
end
subgraph "TypeScript가 생성한 것"
C[notebook-lm-chrome/]
D[Default/]
E[Cookies]
F[Local Storage]
G[Session Storage]
end
A --> B
C --> D --> E & F & G
H[불일치!] --> I[영구적 "Auth required"]
근본 원인
전형적인 크로스 언어 통합 버그다:
- Shell 래퍼가 인증이 어떻게 작동할지에 대한 가정으로 작성됨
- TypeScript 구현이 브라우저 프로필 사용으로 진화함 (더 나은 UX)
- 아무도 래퍼를 업데이트하지 않음 - 새로운 인증 메커니즘에 맞추지 않음
인증 확인 코드가 화석이 되었다 - 더 이상 존재하지 않는 옛 설계를 반영하는 코드.
해결 방법
Shell 스크립트가 실제 아티팩트를 확인하도록 수정했다:
# 이전: 존재하지 않는 JSON 확인
AUTH_FILE="$AUTH_DIR/notebook-lm-auth.json"
if [[ ! -f "$AUTH_FILE" ]]; then
# 이후: Chrome 프로필 디렉토리 확인
CHROME_PROFILE="$AUTH_DIR/notebook-lm-chrome/Default"
if [[ ! -d "$CHROME_PROFILE" ]]; then
디버깅 기법
인증 플로우 완료 후 인증이 “작동하지 않을” 때:
# 1단계: 실제로 무엇이 존재하는지 확인
ls -la ~/.config/moltbot/notebook-lm*
# 출력이 진실을 드러냈다:
# drwxr-xr-x notebook-lm-chrome/ <- 이건 존재한다!
# (no notebook-lm-auth.json) <- 이건 없다!
파일시스템은 거짓말하지 않는다. 코드는 할 수 있지만.
예방 패턴
다중 언어 통합에서는 공유 계약을 만든다:
# auth-contract.yaml
authentication:
mechanism: chrome-profile
location: ~/.config/moltbot/notebook-lm-chrome
validation:
type: directory
check: Default/Cookies exists
# Shell과 TypeScript 모두 이 계약을 읽는다
또는 최소한 상호 참조하는 주석을 추가한다:
# NOTE: 인증 메커니즘은 Chrome 프로필, upload.ts에서 관리
# 참고: src/upload.ts:AUTH_DIR에서 실제 경로 확인
CHROME_PROFILE="$AUTH_DIR/notebook-lm-chrome/Default"
핵심 교훈
- 실제 아티팩트를 추적하라 - 다른 컴포넌트가 무엇을 생성하는지 가정하지 말고 확인하라
- Shell 래퍼는 부패한다 - 한 번 작성되고 구현이 진화하는 동안 잊힌다
- 크로스 언어 = 크로스 가정 - 각 언어는 인증을 다르게 처리하는 경향이 있다
- 파일시스템 디버깅 - 예상 경로에
ls -la하면 불일치가 즉시 드러난다 - 계약을 문서화하라 - 컴포넌트들이 상태를 공유할 때, 그 상태가 어떻게 생겼는지 문서화하라
가장 교활한 버그는 코드 안에 있지 않다 - 코드 사이의 가정 속에 있다.
