Skip to content

[SaveFileView] All PCGamingWiki requests fail with HTTP 403 – Cloudflare now requires a User-Agent header #749

@tiggadry

Description

@tiggadry

Note: I used GitHub Copilot to help investigate and write up this report. The diagnosis and the PowerShell proof below are real and verified on my machine — I just had AI assistance figuring out why it was broken.


Extension name

Save File View

Bug Description

Since approximately late April 2026, all PCGamingWiki data fetching silently fails, resulting in:

Done. Obtained data from 0 game(s). Could not obtain data of N game(s).

This happens both for bulk "Refresh directories from PCGamingWiki" (all games) and for individual single-game refreshes. Previously downloaded/cached JSON files continue to work fine — only new HTTP requests to PCGamingWiki fail.

Root Cause

PCGamingWiki is protected by Cloudflare, which now blocks HTTP requests that do not include a User-Agent header (returns HTTP 403 Forbidden with a Cloudflare block page).

FlowHttp's HttpRequestFactory.GetHttpRequest().WithUrl(uri).DownloadString() sends requests without any User-Agent header by default. Cloudflare treats these as bots and blocks them.

This is consistent with the PCGamingWiki API developer notice from April 26, 2026: "Additional caching + rate limiting have been applied and may affect you if you interface with the MediaWiki API."

Proof

Tested directly using .NET HttpClient (same as FlowHttp uses internally):

Without User-Agent → HTTP 403:

Add-Type -AssemblyName System.Net.Http
$url = "https://www.pcgamingwiki.com/w/api.php?action=cargoquery&tables=Infobox_game&fields=_pageName%3DPageID%2CSteam_AppID&where=Steam_AppID+HOLDS+%221091500%22&format=json"
$client = New-Object System.Net.Http.HttpClient
$response = $client.GetAsync($url).Result
Write-Host "HTTP Status: $($response.StatusCode)"
# Output: HTTP Status: Forbidden

With User-Agent → HTTP 200 OK + valid JSON:

$client.DefaultRequestHeaders.Add("User-Agent", "SaveFileView/1.0 (Playnite Plugin; https://github.com/darklinkpower/PlayniteExtensionsCollection)")
$response = $client.GetAsync($url).Result
Write-Host "HTTP Status: $($response.StatusCode)"
$client.GetAsync($url).Result.Content.ReadAsStringAsync().Result
# Output: HTTP Status: OK
# {"cargoquery":[{"title":{"PageID":"Cyberpunk 2077","Steam AppID":"1091500,..."}}]}

Proposed Fix

Add a User-Agent header to all PCGamingWiki HTTP requests in SaveFileView.cs. The PCGamingWiki API docs recommend the format: clientname/version (contact info) framework/version

// Before (broken since Cloudflare enforcement):
HttpRequestFactory.GetHttpRequest()
    .WithUrl(uri)
    .DownloadString();

// After:
HttpRequestFactory.GetHttpRequest()
    .WithUrl(uri)
    .WithHeaders(new Dictionary<string, string> {
        { "User-Agent", "SaveFileView/1.0 (Playnite Plugin; https://github.com/darklinkpower/PlayniteExtensionsCollection)" }
    })
    .DownloadString();

This affects all three places in SaveFileView.cs that call the PCGamingWiki API:

  • GetPcgwPageId (cargo query by Steam/GOG AppID)
  • GetPcgwPageIdBySearch (search query fallback)
  • GetWikiTextForPageId (wikitext download)

Additional note: Rate limiting for bulk refresh

The PCGamingWiki API also enforces a 30 requests/minute rate limit. When refreshing hundreds of games at once, this will cause HTTP 429 responses after the first ~15 games (each game requires ~2 requests). Consider adding a small delay between requests in RefreshGamesDirectories to stay under the limit.

To Reproduce

  1. Delete the SaveFileView data folder: %AppData%\Playnite\ExtensionsData\f68f302b-9799-4b77-a982-4bfca97130e2\
  2. Select any game(s) with a Steam AppID in Playnite
  3. Right-click → Game menu → SaveFileView: Refresh directories from PCGamingWiki
  4. Result: "Done. Obtained data from 0 game(s)."

Expected Behavior

PCGamingWiki data is fetched successfully and JSON files are created in the data folder.

Environment

  • Plugin version: 2.22
  • Playnite version: 10.55
  • OS: Windows 11 Home
  • PCGamingWiki change: Cloudflare User-Agent enforcement active as of ~April 26, 2026

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions