NickeManarin/ScreenToGif · warning · WebException

Empty response from server when getting language codes path

Error message

Empty response from server when getting language codes path

What it means

A WebException thrown inside GetLanguageCodesPathAsync — the FIRST network call in the language-code pipeline — after WebRequest.Create("https://datahub.io/core/language-codes/datapackage.json") succeeds with an HttpWebResponse but response.GetResponseStream() returns null. This guard protects the JSON parse that extracts the ietf-language-tags_json path. It is the upstream sibling of error 45: if this path request yields a null stream, GetLanguageCodesPathAsync cannot even resolve the URL, so error 44's null-path guard would later fire unless this throws first.

Source

Thrown at ScreenToGif/Windows/Other/Localization.xaml.cs:444

                var languages = json.Elements();

                return await Task.Factory.StartNew(() => languages.Where(x => x.XPathSelectElement("defs")?.Value != "0").Select(x => x.XPathSelectElement("lang")?.Value));
            }
        }
    }

    private async Task<string> GetLanguageCodesPathAsync()
    {
        var request = (HttpWebRequest)WebRequest.Create("https://datahub.io/core/language-codes/datapackage.json");
        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";
        request.Proxy = WebHelper.GetProxy();

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

        using (var resultStream = response.GetResponseStream())
        {
            if (resultStream == null)
                throw new WebException("Empty response from server when getting language codes path");

            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));

                return await Task.Factory.StartNew(() => json.XPathSelectElement("resources")?.Elements().First(x => x.XPathSelectElement("name")?.Value == "ietf-language-tags_json").XPathSelectElement("path")?.Value);
            }
        }
    }

    private void UpdateIndexes()
    {
        var actualIndex = 0;

View on GitHub (pinned to a4d0a67c21)

Solutions

  1. Confirm internet reachability and that https://datahub.io/core/language-codes/datapackage.json returns valid JSON (curl/browser).
  2. Check/adjust WebHelper.GetProxy() — disable the custom proxy or use the system default if it is stripping bodies.
  3. Retry the request once with a short delay; null-stream responses are usually transient.
  4. Fall back to a hardcoded language-codes URL when GetLanguageCodesPathAsync fails, bypassing the datapackage indirection.
  5. Inspect response.StatusCode and ContentLength before treating null stream as fatal — surface the actual status to the user.

Example fix

// before
var response = (HttpWebResponse)await request.GetResponseAsync();
using (var resultStream = response.GetResponseStream())
{
    if (resultStream == null)
        throw new WebException("Empty response from server when getting language codes path");

// after: status check + retry + fallback URL
if ((int)response.StatusCode >= 400)
    throw new WebException($"datahub.io returned {response.StatusCode}");

using (var resultStream = response.GetResponseStream())
{
    if (resultStream == null)
    {
        LogWriter.Log("Empty datapackage.json stream; using fallback language-codes URL.");
        return "https://raw.githubusercontent.com/datasets/language-codes/master/data/ietf-language-tags.json";
    }
Defensive patterns

Strategy: fallback

Validate before calling

// Verify reachability of the datapackage endpoint before the request.
var endpoint = "https://datahub.io/core/language-codes/datapackage.json";
if (!await NetworkHelper.IsReachableAsync(endpoint))
    return "https://raw.githubusercontent.com/datasets/language-codes/master/data/ietf-language-tags.json";

var request = (HttpWebRequest)WebRequest.Create(endpoint);

Type guard

static bool HasReadableBody(HttpWebResponse response) =>
    response != null && (int)response.StatusCode < 400 && response.ContentLength != 0;

var response = (HttpWebResponse)await request.GetResponseAsync();
if (!HasReadableBody(response))
    return /* fallback language-codes URL */;

Try / catch

string path = null;
try
{
    path = await GetLanguageCodesPathAsync();
}
catch (WebException wex) when (wex.Message.Contains("language codes path"))
{
    LogWriter.Log(wex, "datapackage.json body unreadable; using fallback language-codes URL.");
    path = "https://raw.githubusercontent.com/datasets/language-codes/master/data/ietf-language-tags.json";
}
return path;

Prevention

When it happens

Trigger: GetResponseAsync() to datahub.io returned a non-null HttpWebResponse but GetResponseStream() is null. Same transport/proxy edge as error 45 but for the datapackage.json request specifically: broken proxy body-stripping, empty 200 from CDN, TLS early close after headers.

Common situations: No/offline network where a captive portal returns an empty 200; a transparent proxy stripping the JSON body; datahub.io CDN returned Content-Length 0; WebHelper.GetProxy() points at a proxy that drops response bodies; DNS hijack returning an empty page; the datahub.io endpoint is temporarily degraded.

Related errors


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