NickeManarin/ScreenToGif · warning · WebException

File not found

Error message

File not found

What it means

Thrown when DownloadSingleResourceAsync queries the GitHub Contents API for the Localization directory and finds no file whose 'name' field ends with '{culture}.xaml'. The GitHub response is parsed via JsonReaderWriterFactory into XML and filtered with XPath; a null result means the requested culture has no corresponding XAML resource file in the repository.

Source

Thrown at Other/Translator/TranslatorWindow.xaml.cs:355

            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393";

            var response = (HttpWebResponse)await request.GetResponseAsync();

            await using (var resultStream = response.GetResponseStream())
            {
                using (var reader = new StreamReader(resultStream))
                {
                    var result = await reader.ReadToEndAsync();

                    var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(result),
                        new System.Xml.XmlDictionaryReaderQuotas());

                    var json = await Task<XElement>.Factory.StartNew(() => XElement.Load(jsonReader));

                    var element = json.XPathSelectElement("/").Elements().FirstOrDefault(x => x.XPathSelectElement("name").Value.EndsWith(culture + ".xaml"));

                    if (element == null)
                        throw new WebException("File not found");

                    var name = element.XPathSelectElement("name").Value;
                    var downloadUrl = element.XPathSelectElement("download_url").Value;

                    await DownloadFileAsync(new Uri(downloadUrl), name);

                    CommandManager.InvalidateRequerySuggested();
                }
            }
        }
        catch (WebException web)
        {
            Dispatcher.Invoke(() => Dialog.Ok("Translator", "Translator - Downloading Single Resource", web.Message +
                Environment.NewLine + "Trying to load files already downloaded."));

            await LoadFilesAsync();
        }
        catch (Exception ex)

View on GitHub (pinned to a4d0a67c21)

Solutions

  1. Verify the culture code matches an actual file in ScreenToGif/Resources/Localization on the NickeManarin/ScreenToGif repository.
  2. Check if the GitHub API rate limit has been hit (unauthenticated calls are capped at 60/hour) — wait or authenticate the request.
  3. Catch the WebException at the call site and fall back to loading previously downloaded files (the existing catch at line 366 already does this).
  4. Inspect the raw JSON returned by the Contents API to confirm the 'name' and 'download_url' fields exist and have the expected structure.

Example fix

// before
var element = json.XPathSelectElement("/").Elements().FirstOrDefault(x => x.XPathSelectElement("name").Value.EndsWith(culture + ".xaml"));
if (element == null)
    throw new WebException("File not found");

// after: check element AND sub-elements before throwing
var element = json.XPathSelectElement("/").Elements().FirstOrDefault(x =>
    x.XPathSelectElement("name")?.Value.EndsWith(culture + ".xaml") == true);
if (element == null || element.XPathSelectElement("download_url") == null)
    throw new WebException($"No localization file found for culture '{culture}'");
Defensive patterns

Strategy: try-catch

Validate before calling

var response = await client.GetAsync("https://api.github.com/repos/NickeManarin/ScreenToGif/contents/ScreenToGif/Resources/Localization");
if (!response.IsSuccessStatusCode)
    return null; // don't proceed with parsing
var json = await response.Content.ReadAsStringAsync();
if (string.IsNullOrWhiteSpace(json) || !json.TrimStart().StartsWith("["))
    return null; // not a directory listing

Try / catch

try
{
    await DownloadSingleResourceAsync(culture);
}
catch (WebException ex)
{
    // The existing catch at line 366 already falls back to local files
    await LoadFilesAsync();
}

Prevention

When it happens

Trigger: Calling DownloadSingleResourceAsync with a culture code (e.g. 'zh-Hans') that does not match any file name ending in that culture + '.xaml' within the ScreenToGif/Resources/Localization directory on GitHub. Also occurs if the GitHub API returns an unexpected JSON shape (e.g. an error object or rate-limit response) so that the XPath filter yields no elements.

Common situations: Translator tool is pointed at a culture code that has no uploaded translation file yet. GitHub API rate limit (60 requests/hour unauthenticated) returns a JSON error object instead of a directory listing, so no element matches. Repository folder was renamed or restructured.

Related errors


AI-assisted analysis of NickeManarin/ScreenToGif@a4d0a67c21 (2026-08-13). Data as JSON: /api/errors/a3ef8ed0f0b602cf. Report an issue: GitHub.