โทเคนก็ถูกต้อง แต่ Headless Agent ของผมกลับติด 401 อยู่ดี

ผมสร้างเครื่องมือเล็กๆ สองตัวเพื่อเรียกใช้งาน Claude ผ่านโค้ด ตัวหนึ่งใช้สำหรับสร้าง commit messages ส่วนอีกตัวใช้สำหรับอัปเดตโปรไฟล์

โค้ดดูสมบูรณ์แบบมาก มันดึง API key จาก environment ส่งคำขอ HTTPS แบบ raw ไปยัง Anthropic API และ parse JSON response ออกมา

แต่มันกลับล้มเหลวทุกครั้งด้วย error 401

ปัญหาไม่ได้อยู่ที่โค้ด แต่อยู่ที่วิธีการยืนยันตัวตน (authentication method)

ผมไม่ได้ใช้ API key แบบตรงๆ แต่ผมใช้ Claude Code ผ่านการสมัครสมาชิก (subscription) ซึ่งใช้ OAuth ผ่าน Claude CLI นี่เป็นระบบที่แตกต่างจากสิ่งที่สคริปต์ของผมคาดหวังไว้

ใน environment ของผมมีค่าที่ล้าสมัยหรือว่างเปล่าอยู่ในตัวแปร API key สคริปต์ตรวจพบค่าบางอย่างจึงคิดว่ามันถูกต้อง คำขอจึงถูกส่งออกไปพร้อมกับ credential ประเภทที่ผิด

วิธีแก้ไขนั้นง่ายมาก ผมเลิกส่งคำขอ API โดยตรง แต่เปลี่ยนไปสั่งให้สคริปต์ใช้ CLI ที่มี session ที่ใช้งานได้อยู่แล้วแทน

วิธีเดิม: ใช้ urllib เพื่อส่งคำขอพร้อมกับ API key

วิธีใหม่: ใช้ subprocess เพื่อรันคำสั่ง "claude" โดยตรง

CLI จะจัดการเรื่อง session, tokens และการหมดอายุให้คุณเอง

ความผิดพลาดนี้อันตรายมากใน headless environments เพราะถ้าเป็นคน คุณจะเห็น error ใน terminal แต่ถ้าเป็น cron job หรือ CI pipeline มันจะล้มเหลวเงียบๆ (fail silently) จนคุณอาจไม่สังเกตเห็นเลยเป็นเวลาหลายวัน

คุณจะเห็นรูปแบบเดียวกันนี้ในที่อื่นๆ:

  • เครื่องมือมองหา personal access token แต่ระบบกลับใช้ OIDC
  • สคริปต์อ่าน AWS keys ในขณะที่ระบบใช้ IAM role

โทเคนมีอยู่จริง รูปแบบก็ถูกต้อง ผ่านการตรวจสอบเบื้องต้นได้ แต่กลับใช้กลไก (mechanism) ที่ผิด

ทำตามกฎเหล่านี้เพื่อหลีกเลี่ยงปัญหาดังกล่าว:

  • สอบถามว่า environment ของคุณใช้วิธีการยืนยันตัวตนแบบใดก่อนที่จะเริ่มเขียนโค้ด อย่าทำตามแค่ API documentation เท่านั้น
  • อย่าเชื่อใจ os.environ ค่าที่มีอยู่อาจจะล้าสมัยหรือผิดพลาดได้
  • หากมีเครื่องมือ CLI ที่จัดการเรื่องการยืนยันตัวตนให้คุณอยู่แล้ว ให้ใช้มัน แทนที่จะเขียน logic การ auth ขึ้นมาใหม่เอง ให้ใช้วิธีเรียกใช้ CLI ผ่าน shell แทน
  • หากคุณเจอ error 401 ให้ตรวจสอบเส้นทางของ credential ก่อนที่จะไปแก้ไขโค้ดในส่วนการส่งคำขอ

ที่มา: https://dev.to/enjoy_kumawat/the-token-was-valid-my-headless-agent-401d-anyway-3bgl

ชุมชนแห่งการเรียนรู้เพิ่มเติม: https://t.me/GyaanSetuAi