NickeManarin/ScreenToGif · error · UploadException

Unknown error

Error message

Unknown error

What it means

YandexDisk.UploadFileAsync requests an upload URL from cloud-api.yandex.net/v1/disk/resources/upload and expects a Link object with a non-empty Href. If Href is null/empty, it throws a generic UploadException("Unknown error"). Note: real API errors are caught separately inside GetAsync (error 24), so reaching this line means Yandex returned a parseable but Href-less response body.

Source

Thrown at ScreenToGif/Cloud/YandexDisk.cs:29

using ScreenToGif.Util.Settings;
using ScreenToGif.ViewModel.UploadPresets.History;
using ScreenToGif.ViewModel.UploadPresets.Yandex;

namespace ScreenToGif.Cloud;

public class YandexDisk : IUploader
{
    public async Task<IHistory> UploadFileAsync(IUploadPreset preset, string path, CancellationToken cancellationToken, IProgress<double> progressCallback = null)
    {
        if (string.IsNullOrEmpty(path)) 
            throw new ArgumentException(nameof(path));

        var fileName = Path.GetFileName(path);

        var link = await GetAsync<Link>(preset as YandexPreset, "https://cloud-api.yandex.net/v1/disk/resources/upload?path=app:/" + fileName + "&overwrite=true", cancellationToken);
            
        if (string.IsNullOrEmpty(link?.Href)) 
            throw new UploadException("Unknown error");

        await using (var fileSteram = new FileStream(path, FileMode.Open, FileAccess.Read))
        {
            await PutAsync(preset as YandexPreset, link.Href, new StreamContent(fileSteram), cancellationToken);
        }

        var downloadLink = await GetAsync<Link>(preset as YandexPreset, "https://cloud-api.yandex.net/v1/disk/resources/download?path=app:/" + fileName, cancellationToken);

        var history = new History
        {
            Type = preset.Type,
            PresetName = preset.Title,
            DateInUtc = DateTime.UtcNow,
            Result = 200,
            Link = downloadLink.Href
        };
            
        return history;

View on GitHub (pinned to a4d0a67c21)

Solutions

  1. Re-authorize the Yandex account to refresh preset.OAuthToken.
  2. Log the raw responseBody inside GetAsync when Link.Href is empty so the actual payload can be inspected.
  3. Sanitize the file name (strip characters illegal for Yandex paths) before building the upload URL.
  4. If it persists, treat it as an API contract change and update the Link DTO to match Yandex's current schema.

Example fix

// before
if (string.IsNullOrEmpty(link?.Href)) 
    throw new UploadException("Unknown error");

// after
if (string.IsNullOrEmpty(link?.Href)) 
    throw new UploadException($"Unknown error: Yandex returned no upload Href for file '{fileName}'. Re-authorize the Yandex account.");
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check the parsed upload link before throwing
if (string.IsNullOrEmpty(link?.Href))
{
    LogWriter.Log($"Yandex upload-URL response missing Href. Token valid: {!string.IsNullOrWhiteSpace((preset as YandexPreset)?.OAuthToken)}");
}

Type guard

bool HasYandexUploadHref(Link l) => !string.IsNullOrWhiteSpace(l?.Href);

Try / catch

try { var link = await GetAsync<Link>(...); }
catch (UploadException ex) { LogWriter.Log(ex, "Yandex upload URL"); throw; }

Prevention

When it happens

Trigger: GetAsync<Link> succeeds (no ErrorDescriptor.Error) but the deserialized Link.Href is null or empty string. Happens when the JSON shape changed, a required field was renamed, or the response was an unexpected success-shaped payload.

Common situations: Yandex API version drift (field renamed from href to something else); malformed filename producing a degenerate response; proxy returning a 200 with an HTML interstitial that deserialized to an empty object;OAuth token valid but app folder not provisioned yet.

Related errors


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