Files
OpenQode/Documentation/QWEN_AUTH_FIX_DOCUMENTATION.md

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:

  • qwen CLI v0.5.0-nightly had broken -p flag
  • 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.js instead
  • 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 --version check
  • 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.js instead of opencode.exe

bin/opencode-tui.cjs

  • Lines 685-718: Updated startup auth to use node bin/auth.js
  • Fixed auth check logic to properly validate .authenticated property

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

  1. No Refresh Token in Shared Storage: When using shared tokens from opencode.exe, they don't include refresh_token. Users must re-authenticate when tokens expire.

  2. OAuth Requires Client ID: Tier 2 (OAuth) requires QWEN_OAUTH_CLIENT_ID in config.cjs. Most users will use Tier 1 (bundled CLI) instead.

  3. Session Duration: Qwen tokens expire after ~24 hours. This is a Qwen limitation, not an OpenQode issue.

Future Improvements

  1. Implement token refresh endpoint scraping from CLI
  2. Add automatic re-auth trigger when needsAuth: true
  3. Create visual auth status indicator in TUI
  4. Add token validity pre-check before API calls

Commit History

All changes committed in 14 commits:

  1. fix: Windows auth check for Goose, TUI, and launcher
  2. fix: Use opencode.exe auth qwen for authentication
  3. fix: Share tokens with opencode.exe
  4. fix: Replace CLI with direct Qwen Chat API
  5. fix: Remove orphaned JSDoc comment causing syntax error
  6. fix: Use chat.qwen.ai /v1/ endpoint for OAuth
  7. feat: Add automatic token refresh on 401 errors
  8. feat: Save tokens to shared location
  9. feat: Make OpenQode.bat independent of opencode.exe
  10. fix: Correct qwen-oauth require path in auth.js
  11. fix: Update error messages to use 'node bin/auth.js'
  12. fix: Update TUI startup auth to use node bin/auth.js
  13. feat: Implement 3-tier cascading authentication
  14. feat: Bundle official Qwen CLI with OpenQode

For Future AI Models

If you encounter authentication issues:

  1. Check token location: ~/.opencode/qwen-shared-tokens.json
  2. Verify API endpoint: Must be https://chat.qwen.ai/api/v1/chat/completions
  3. Test bundled CLI: node node_modules/.bin/qwen --version
  4. Run auth: node bin/auth.js (cascading fallback)
  5. Check logs: Look for "Session expired" or "401" errors

DO NOT:

  • Use qwen -p flag (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