duplicati/duplicati · error · UserInformationException

UrlOptionMissing

UrlOptionMissing

Error message

URL is required

What it means

Thrown by GetApiKeyModule.Execute when the 'url' option is null or empty. The module needs the Filen backend URL (including any query parameters it later parses via RelaxedUri) to construct a FilenBackend, so a missing URL is a hard configuration failure surfaced as UserInformationException code 'UrlOptionMissing'.

Source

Thrown at Duplicati/Library/Backend/Filen/GetApiKeyModule.cs:64

    }

    /// <inheritdoc/>
    public IList<ICommandLineArgument> SupportedCommands =>
    [
        .. AuthOptionsHelper.GetOptions(),
        new CommandLineArgument("two-factor", CommandLineArgument.ArgumentType.String, Strings.FilenBackend.TwoFactorShort, Strings.FilenBackend.TwoFactorLong)
    ];

    /// <inheritdoc/>
    public async Task<IDictionary<string, string>> Execute(IDictionary<string, string?> options, CancellationToken cancellationToken)
    {
        options.TryGetValue("filen-operation", out var operation);
        if (operation != "GetApiKey")
            throw new UserInformationException("Invalid operation", "InvalidOperation");

        options.TryGetValue("url", out var url);
        if (string.IsNullOrEmpty(url))
            throw new UserInformationException("URL is required", "UrlOptionMissing");

        var uri = new Utility.RelaxedUri(url);

        var newOpts = new Dictionary<string, string?>(options);
        foreach (var key in uri.QueryParameters.AllKeys)
            if (key != null)
                newOpts[key] = uri.QueryParameters[key];

        var backend = new FilenBackend(url, newOpts);
        var apiKey = await backend.GetApiKey(cancellationToken).ConfigureAwait(false);
        return new Dictionary<string, string> { { "api-key", apiKey ?? string.Empty } };
    }

    /// <inheritdoc/>
    public IDictionary<string, IDictionary<string, string>> GetLookups()
        => new Dictionary<string, IDictionary<string, string>>();
}

View on GitHub (pinned to 3f348be3e3)

Solutions

  1. Supply a non-empty --url=<filen-connection-string> when invoking the module.
  2. Validate that the option is present and well-formed in your wrapper before launching the module.
  3. Ensure the option key is exactly 'url' (not 'uri', 'host', or 'destination').

Example fix

// before
options.TryGetValue("url", out var url);
if (string.IsNullOrEmpty(url))
    throw new UserInformationException("URL is required", "UrlOptionMissing");

// after (whitespace-aware + clearer message)
if (string.IsNullOrWhiteSpace(url))
    throw new UserInformationException(
        "The 'url' option is required for the Filen get-api-key module (e.g. filen://user@example.com).",
        "UrlOptionMissing");
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(options.GetValueOrDefault("url")))
    throw new ArgumentException("The 'url' option is required for the Filen get-api-key module.");

Try / catch

try { await module.Execute(options, ct); }
catch (UserInformationException ex) when (ex.HelpID == "UrlOptionMissing")
{
    Console.Error.WriteLine("Supply --url=<filen-connection-string>.");
    throw;
}

Prevention

When it happens

Trigger: Calling the 'filen-get-api-key' module without a 'url' option, or with an empty/whitespace value. The check happens after the operation check and before RelaxedUri parsing, so an empty string fails here rather than later in RelaxedUri.

Common situations: Running the module without the destination URL argument; a template/config that omits the Filen URL; passing the URL under a different option name (e.g. 'host' instead of 'url').

Related errors


AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13). Data as JSON: /api/errors/1c6518d3fa27c473. Report an issue: GitHub.