How wechat-article-exporter Handles WeChat API Session Expiration (ret code 200003)

When the WeChat MP backend returns ret code 200003, the exporter automatically invalidates the stored authentication cookie, triggers a re-login flow via QR code, and retries the failed request once the session is restored.

The wechat-article-exporter project provides a robust solution for exporting WeChat articles by interfacing with the official WeChat MP (Weixin Official Accounts Platform) backend. When your WeChat API session expires—signaled by the specific error code ret = 200003—the application implements a seamless recovery mechanism that clears stale credentials and guides you through re-authentication without losing export progress.

Understanding the WeChat API Session Expiration Signal

WeChat MP endpoints return a JSON payload containing a base_resp object with a ret status code. While ret: 0 indicates success, ret code 200003 specifically means "session expired" or "login status expired," requiring immediate re-authentication.

The WeChat MP Response Structure

When the session cookie (containing the token obtained from QR-code login) becomes invalid, the API responds with:

{
  "base_resp": { 
    "ret": 200003, 
    "err_msg": "session expired" 
  }
}

According to the source code analysis, the exporter treats this ret = 200003 as a definitive session-expiration signal that triggers the credential refresh workflow.

Detecting ret code 200003 in the Proxy Layer

All frontend requests route through the central proxy utility located at server/utils/proxy-request.ts. The proxyMpRequest() function forwards every request to the WeChat MP backend and inspects the response for session expiration.

After receiving the response via fetch(), the code parses the JSON and checks the base_resp.ret value:

// server/utils/proxy-request.ts
const json = await finalResponse.json();
if (json.base_resp?.ret === 200003) {
  // Forward the error to the caller with HTTP 401
  return new Response(JSON.stringify(json), { status: 401 });
}
return json;   // Normal path for ret === 0

This detection ensures that any WeChat API session expiration is immediately surfaced to the frontend with a standard HTTP 401 status code, separating transport errors from authentication failures.

Recovering from Session Expiration

When the proxy detects ret = 200003, the frontend composable useLoginCheck.ts intercepts the error and initiates a three-phase recovery process.

Clearing Stale Authentication Data

The useLoginCheck composable performs critical cleanup operations when it encounters the 200003 error:

  1. Removes the server-side session: Calls the /api/web/login/logout endpoint to purge the auth-key from KV storage via CookieStore.setCookie and CookieStore.updateCookie methods defined in server/utils/CookieStore.ts
  2. Emits logout event: Dispatches a logout event through useAccountEventBus to notify all components of the authentication state change
  3. Forces UI transition: Redirects the user to the login page to initiate fresh QR-code authentication
// composables/useLoginCheck.ts
export function useLoginCheck() {
  const { callMpApi } = useApis();
  const accountBus = useAccountEventBus();

  async function guardedCall(options) {
    const resp = await callMpApi(options);
    if (resp.base_resp?.ret === 200003) {
      // Session expired → clear auth-key and ask user to log in again
      await fetch('/api/web/login/logout'); // removes KV entry
      accountBus.emit('logout');
      throw new Error('WeChat session expired – please log in again.');
    }
    return resp;
  }

  return { guardedCall };
}

The Logout API Endpoint

The server/api/web/login/logout.get.ts endpoint handles the server-side removal of stored session data from the KV store. This ensures the stale auth-key cannot be reused by subsequent requests, preventing infinite loops of invalid authentication attempts.

Automatic Retry After Re-Authentication

Once the user completes the QR-code login flow again and obtains fresh cookies, the composables/useDownloader.ts logic automatically retries the original failed request. This happens transparently without requiring manual restart of the export process, ensuring that ret code 200003 interruptions do not result in data loss or failed exports.

The retry mechanism works by wrapping API calls with the guardedCall function from useLoginCheck, catching session errors, waiting for the re-authentication event, and then re-issuing the request with the new valid cookies.

Summary

Frequently Asked Questions

What does WeChat API ret code 200003 mean?

Ret code 200003 indicates that the session cookie containing your WeChat MP authentication token has expired or become invalid. The WeChat backend returns this code in the base_resp.ret field when it can no longer associate your request with a valid logged-in user session, requiring you to re-authenticate via QR code.

Which file handles the detection of session expiration?

The server/utils/proxy-request.ts file contains the proxyMpRequest() function that inspects every WeChat MP response. After parsing the JSON with finalResponse.json(), it specifically checks for json.base_resp?.ret === 200003 and returns an HTTP 401 response to signal the frontend that re-authentication is required.

How does wechat-article-exporter store session credentials?

The application uses a KV-backed CookieStore implemented in server/utils/CookieStore.ts. The auth-key and associated WeChat cookies are persisted in KV storage with methods like CookieStore.setCookie() and CookieStore.updateCookie(), allowing the server to maintain your session across requests until a ret code 200003 error triggers cleanup.

Will my download progress be lost when re-authenticating?

No. The composables/useDownloader.ts composable implements automatic retry logic that re-issues failed requests once the useLoginCheck composable confirms a fresh session is established. Since the download state is maintained independently of the authentication layer, the export resumes from where it left off after you complete the QR-code login flow.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →