# Troubleshooting & Diagnostic Guide

When resolution, validation, or playback fails, use this decision tree and error code reference to diagnose and resolve the root cause.

---

## Diagnostic Decision Tree

```
                      API Request Executed
                               │
            ┌──────────────────┴──────────────────┐
            ▼                                     ▼
     HTTP 200 (success: true)             HTTP 502 (success: false)
            │                                     │
   ┌────────┴────────┐                   ┌────────┴────────┐
   ▼                 ▼                   ▼                 ▼
Video Plays    Browser Player       Extraction        Preflight Media
Successfully    Fails to Load         Fails          Validation Fails
 (SUCCESS)           │                   │                 │
                     ▼                   ▼                 ▼
             Check HLS / CORS /    Inspect Provider   Inspect Upstream
             Playback Headers       Attempts & Logs     URL & Proxies
```

---

## Step-by-Step Diagnostics

### 1. API Returns `HTTP 502` (`success: false`)

If the API returns `502 Bad Gateway`, check the `attempts` array in the JSON response payload.

#### Case A: Provider Extraction Error
Example Error: `VIDSRC_TO_PLAYER_FAILED`, `VIDNEST_RUNTIME_RESOLUTION_FAILED`
- **Cause**: Upstream provider iframe structure, API endpoint, or WASM URL changed or timed out.
- **Action**:
  1. Inspect provider implementation source code (`src/providers/<provider>/index.ts`).
  2. Run live test using environment variable: `RUN_LIVE_TESTS=1 npm test`.

#### Case B: Preflight Validation Error (`MEDIA_VALIDATION_FAILED`)
Example Error: `HLS_PLAYLIST_INVALID`, `HLS_HTML_RESPONSE`, `HLS_REQUIRES_SESSION`
- **Cause**: Provider returned a stream candidate URL, but preflight validation failed during playlist/segment probing.
- **Common Diagnostics**:
  - `HLS_HTML_RESPONSE`: Upstream server returned an HTML anti-bot challenge or block page instead of an `.m3u8` playlist.
  - `HLS_REQUIRES_SESSION`: Upstream server returned HTTP 401/403 or "not in range" plaintext session error.
  - `HLS_SEGMENT_UNREACHABLE`: Master playlist was valid, but variant segment URLs returned HTTP 404 or connection timeout.
- **Action**:
  1. Check if stream requires `/api/media-proxy` wrapper.
  2. Verify if upstream host domain top-level extension (e.g. `.website`, `.su`) is listed in `isApprovedMediaHost` in `src/core/proxy.ts`.

---

### 2. API Returns `HTTP 200` (`success: true`), but Browser Player Fails to Play

If the API successfully returns a source object, but the video element in the browser fails to play:

#### Case A: "HLS manifest load error" / Network Error in Browser Console
- **Cause**: Attempting to play `.m3u8` directly in Chrome/Firefox without an HLS client library (such as `hls.js`), or browser CORS blocking.
- **Action**: Ensure downstream web clients attach an HLS engine (e.g. `hls.js`) to parse m3u8 manifests and pass custom headers.

#### Case B: "403 Forbidden" on Proxy Segment Requests
- **Cause**: Host target in `/api/media-proxy?url=...` is rejected by `isApprovedMediaHost`.
- **Action**: Check if the host domain matches allowlist patterns in `src/core/proxy.ts`.

---

## Error Code Reference

| Error Code | HTTP Status | Description |
| --- | --- | --- |
| `INVALID_REQUEST` | `400` | Missing or malformed parameters (e.g., missing TMDB ID or TV season/episode). |
| `ACCESS_DENIED` | `403` | Proxy target domain prohibited by SSRF security allowlist. |
| `INTERNAL_ERROR` | `500` | Unhandled edge error inside Worker execution. |
| `EXTRACTION_FAILED` | `502` | Provider failed to extract raw stream candidates from upstream embed/API. |
| `MEDIA_VALIDATION_FAILED` | `502` | Preflight validation engine rejected candidates (HTML response, 404 segment, missing key). |
| `PROVIDER_UNAVAILABLE` | `502` | Upstream provider domain returned 5xx server errors or connection timeout. |
| `VIDNEST_RUNTIME_RESOLUTION_FAILED` | `502` | VidNest failed across all configured priority servers (`alfa`, `gama`, `prime`, etc.). |

---

## Gateway Timeout vs Resolution Budgeting

- **Execution Budgeting**: The extractor pipeline enforces an overall timeout budget (8.5s) with individual provider caps (3.2s - 3.8s) and fast request parsing fallback, guaranteeing that responses return structured JSON before platform or edge gateway timeouts.

## HLS.js `manifestLoadError` after successful resolution

A successful resolver response means extraction and server-side validation completed; it does not prove the browser can play the stream. Use the demo player's browser playback timeline to identify the failing stage:

- `Manifest request started` followed by a fatal `manifestLoadError` usually means the browser could not load `/api/media-proxy` or the proxy rejected the upstream manifest.
- An HTTP status in the HLS.js error indicates an upstream/proxy HTTP failure.
- `NETWORK_ERROR_OR_CORS` without a status may indicate CORS, DNS, timeout, or browser-blocked network behavior.
- Variant or segment failures after manifest parsing mean the master loaded but child resources did not retain the required proxy/token/header context.

For Vidsrc.to specifically, use dynamic `__TOKEN__` proxy URLs and verify that rewritten child resources still include `tokenUrl`, `tokenReferer`, and the upstream `referer` query parameters.

### Vidsrc.to master request returns HTTP 403

When Vidsrc.to fails with `HLS_REQUIRES_SESSION: MASTER_REQUEST_FAILED`, the browser has not received a playable source yet. Inspect the attempt diagnostics rather than the top-level `success: false` fields:

- `diagnostics.stage` identifies the failing HLS stage, for example `MASTER`.
- `diagnostics.status` records the upstream HTTP status.
- `diagnostics.url` redacts secrets and omits query values.
- `diagnostics.query.present`, `diagnostics.query.keys`, and `diagnostics.query.token` indicate whether query parameters and a token were present without exposing the token.

Do not bypass validation for this case. A 403 master response means the source is not server-validated and must remain unavailable until the required token/session/request context is reproduced legitimately.

If the UI shows one H4sIA route in the resolved proxy URL but validator diagnostics show another, first check whether there were two validation passes: provider-internal validation and resolver-level validation of the returned proxied URL. Dynamic Vidsrc.to proxy URLs must resolve `__TOKEN__` during both passes; otherwise the second pass can validate a different or placeholder token context and fail at `MASTER` with HTTP 403.
