7.3 KiB
Qwen Authentication - Complete Fix Documentation
Overview
This document details all the authentication fixes applied to OpenQode to resolve Qwen authentication issues across all tools (Launcher, TUI Gen5, Goose).
Problem Statement
The Qwen authentication system was completely broken:
qwenCLI v0.5.0-nightly had broken-pflag- Tools couldn't authenticate independently
- No token sharing between tools
- CLI detection was incorrect
- Session expiry wasn't handled
Solutions Implemented
1. Shared Token Storage
Files Changed: qwen-oauth.mjs, qwen-oauth.cjs
All tools now share tokens via ~/.opencode/qwen-shared-tokens.json:
// loadTokens() checks shared location first
const sharedTokenFile = path.join(os.homedir(), '.opencode', 'qwen-shared-tokens.json');
// saveTokens() writes to both locations
await writeFile(sharedTokenFile, JSON.stringify(sharedData, null, 2));
Result: Authenticate once, all tools work.
2. Direct API Integration
File Changed: qwen-oauth.mjs (lines 385-546)
Replaced broken CLI-based messaging with direct Qwen Chat API:
const response = await fetch('https://chat.qwen.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.tokens.access_token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ model, messages, stream })
});
Result: No dependency on broken qwen -p CLI command.
3. Correct API Endpoint
File Changed: qwen-oauth.mjs (line 40)
Fixed endpoint URL:
- ❌ Wrong:
https://chat.qwen.ai/api/chat/completions - ❌ Wrong:
https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions - ✅ Correct:
https://chat.qwen.ai/api/v1/chat/completions
Result: API calls work with OAuth tokens.
4. Auto Token Refresh
File Changed: qwen-oauth.mjs (lines 485-493)
Handles 401 errors with automatic refresh:
if (response.status === 401) {
if (this.tokens?.refresh_token) {
await this.refreshToken();
// Retry request
} else {
return { error: 'Session expired...', needsAuth: true };
}
}
Result: Graceful session expiry handling.
5. Fixed CLI Detection
Files Changed: qwen-oauth.mjs, qwen-oauth.cjs, auth-check.mjs
Corrected CLI detection from broken command to proper version check:
// Before: exec('qwen -p "ping" --help 2>&1') ❌
// After: spawn('qwen', ['--version']) ✅
Result: Accurate CLI availability detection.
6. Independent Authentication
Files Changed: auth-check.mjs, opencode-tui.cjs, auth.js
Removed dependency on opencode.exe:
- Uses
node bin/auth.jsinstead - Works on all platforms
- No external executable required
Result: Cross-platform compatible authentication.
7. 3-Tier Cascading Authentication
File Changed: bin/auth.js
Intelligent fallback system:
Tier 1: Official Qwen CLI (bundled or global)
↓ (if not found)
Tier 2: OAuth Device Flow (if client ID configured)
↓ (if OAuth fails)
Tier 3: Manual Instructions (clear guidance)
Result: Multiple paths to successful authentication.
8. Bundled Official CLI
Files Changed: package.json, bin/auth.js
Added @qwen-code/qwen-code as dependency:
"dependencies": {
"@qwen-code/qwen-code": "^0.5.0",
...
}
Auth detection prioritizes local bundled CLI:
const localCLI = path.join(__dirname, '..', 'node_modules', '.bin', 'qwen');
if (fs.existsSync(localCLI)) {
// Use bundled CLI
}
Result: Out-of-the-box authentication for all users.
File-by-File Changes
qwen-oauth.mjs (ESM)
- Lines 84-116: Updated
loadTokens()- reads from shared location - Lines 118-152: Updated
saveTokens()- writes to both local and shared - Lines 324-376: Fixed
checkAuth()- uses--versioncheck - Lines 385-546: Replaced
sendMessage()- direct API calls - Line 40: Corrected API endpoint URL
qwen-oauth.cjs (CommonJS)
- Lines 65-94: Updated
loadTokens()- shared token support - Lines 256-282: Fixed
checkAuth()- proper CLI detection
bin/auth-check.mjs
- Lines 57-91: Changed to use
node bin/auth.jsinstead ofopencode.exe
bin/opencode-tui.cjs
- Lines 685-718: Updated startup auth to use
node bin/auth.js - Fixed auth check logic to properly validate
.authenticatedproperty
bin/auth.js
- Complete rewrite: 3-tier cascading authentication system
- Lines 39-58: Smart CLI detection (local + global)
- Lines 61-109: Tier 1 - Official CLI launcher
- Lines 111-130: Tier 2 - OAuth device flow
- Lines 132-148: Tier 3 - Manual instructions
package.json
- Added
@qwen-code/qwen-code": "^0.5.0"dependency
Testing Checklist
- Launcher (OpenQode.bat) triggers auth correctly
- TUI Gen5 detects session expiry
- Goose can use shared tokens
- Auth cascades through all 3 tiers
- Bundled CLI is detected and used
- API calls work with correct endpoint
- Tokens are shared across all tools
- Error messages guide users correctly
Known Limitations
-
No Refresh Token in Shared Storage: When using shared tokens from
opencode.exe, they don't includerefresh_token. Users must re-authenticate when tokens expire. -
OAuth Requires Client ID: Tier 2 (OAuth) requires
QWEN_OAUTH_CLIENT_IDin config.cjs. Most users will use Tier 1 (bundled CLI) instead. -
Session Duration: Qwen tokens expire after ~24 hours. This is a Qwen limitation, not an OpenQode issue.
Future Improvements
- Implement token refresh endpoint scraping from CLI
- Add automatic re-auth trigger when
needsAuth: true - Create visual auth status indicator in TUI
- Add token validity pre-check before API calls
Commit History
All changes committed in 14 commits:
fix: Windows auth check for Goose, TUI, and launcherfix: Use opencode.exe auth qwen for authenticationfix: Share tokens with opencode.exefix: Replace CLI with direct Qwen Chat APIfix: Remove orphaned JSDoc comment causing syntax errorfix: Use chat.qwen.ai /v1/ endpoint for OAuthfeat: Add automatic token refresh on 401 errorsfeat: Save tokens to shared locationfeat: Make OpenQode.bat independent of opencode.exefix: Correct qwen-oauth require path in auth.jsfix: Update error messages to use 'node bin/auth.js'fix: Update TUI startup auth to use node bin/auth.jsfeat: Implement 3-tier cascading authenticationfeat: Bundle official Qwen CLI with OpenQode
For Future AI Models
If you encounter authentication issues:
- Check token location:
~/.opencode/qwen-shared-tokens.json - Verify API endpoint: Must be
https://chat.qwen.ai/api/v1/chat/completions - Test bundled CLI:
node node_modules/.bin/qwen --version - Run auth:
node bin/auth.js(cascading fallback) - Check logs: Look for "Session expired" or "401" errors
DO NOT:
- Use
qwen -pflag (broken in v0.5.0-nightly) - Hardcode opencode.exe paths (not cross-platform)
- Skip shared token storage (breaks tool integration)
- Use wrong API endpoints (causes 401/504 errors)
References
- Qwen OAuth Docs: https://github.com/QwenLM/qwen-code
- Working Implementation: https://github.com/roman-ryzenadvanced/OpenQode-Public-Alpha
- Chat API Endpoint: https://chat.qwen.ai/api/v1/chat/completions