datawhalechina/hello-agents · error

HTTP error: ${response.status}

Error message

HTTP error: ${response.status}

What it means

Guard in startNewGame(): POST to a HARDCODED http://localhost:8000/api/game/start that throws on any non-2xx status. Because the URL is hardcoded, deploying this frontend anywhere non-local guarantees either CORS failures (which reject fetch entirely) or 4xx/5xx that land here.

Source

Thrown at Co-creation-projects/afei-GuessWhoAmI/frontend/app.js:51

    // Play again button (HTML id="play-again")
    document.getElementById('play-again')
        .addEventListener('click', () => this.restartGame());
  }

  // Start new game
  async startNewGame() {
    try {
      this.setStartBtnLoading(true);
      this.showLoadingOverlay();

      const response = await fetch('http://localhost:8000/api/game/start', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({})
      });

      if (!response.ok) throw new Error(`HTTP error: ${response.status}`);

      const result = await response.json();

      if (!result.success) throw new Error(result.error || '启动失败');

      const data = result.data;
      this.sessionId = data.session_id;
      this.remainingQuestions = data.max_questions || 20;
      this.remainingHints = data.max_hints || 3;

      // Switch to game screen
      document.getElementById('intro-section').classList.add('hidden');
      document.getElementById('game-section').classList.remove('hidden');
      document.getElementById('result-modal').classList.add('hidden');

      // Enable controls
      document.getElementById('user-input').disabled = false;
      document.getElementById('send-btn').disabled = false;

View on GitHub (pinned to 606a07d341)

Solutions

  1. Replace the hardcoded URL with a config-derived base: same-origin '' in production behind one proxy, or import.meta.env.VITE_API_BASE / window.location.origin fallback in dev
  2. Confirm the backend actually serves /api/game/start on 8000 (curl -i -X POST http://localhost:8000/api/game/start)
  3. Enable CORS on the backend for the frontend origin if you keep cross-origin calls
  4. If 422/500, read response body detail and include it in the thrown error

Example fix

// before
const response = await fetch('http://localhost:8000/api/game/start', {...});

// after
const API_BASE = window.location.origin.startsWith('http://localhost') ? '' : (window.API_BASE_URL || '');
const response = await fetch(`${API_BASE}/api/game/start`, {...});
Defensive patterns

Strategy: validation

Validate before calling

const API_BASE = import.meta.env?.VITE_API_BASE ?? (location.hostname === 'localhost' ? 'http://localhost:8000' : '');

Try / catch

try { await startNewGame(); } catch (e) { alert(`启动失败:${e.message}`); }

Prevention

When it happens

Trigger: Backend not running on port 8000 of the user's machine; accessing the deployed site from another device (localhost refers to the visitor's machine); backend returns 422/500 on start; reverse proxy at a different path.

Common situations: Site deployed to Vercel/GitHub Pages but backend is a local demo server; teammate opens the page on their laptop where nothing listens on 8000; backend moved to /api prefix change or port change.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/6beec576ff922029. Report an issue: GitHub.