tonhowtf/omniget · error

vimeo:bad_url

vimeo:bad_url

Error message

vimeo:bad_url

What it means

vimeo:bad_url is raised by the `list` function when `parse_target(&opts.url)` returns None, meaning the provided URL (or bare id) is empty or not a Vimeo link shape the library recognizes. The library only accepts numeric video ids, showcase/album/channel/user URLs, and unlisted video links (`vimeo.com/<id>/<hash>`). It is a fail-fast validation error thrown before any yt-dlp process is spawned.

Solutions

  1. Inspect `opts.url` and replace it with a valid Vimeo collection URL such as https://vimeo.com/showcase/<id>, https://vimeo.com/album/<id>, https://vimeo.com/channels/<name>, or https://vimeo.com/<username>.
  2. Trim whitespace and ensure the field is not empty before calling list(); an empty/whitespace string returns None.
  3. If you only have a bare numeric id, pass the id alone (e.g. "123456789") — but note bare ids parse as Target::Video and will then fail vimeo:not_a_collection.
  4. Check src-tauri/omniget-core/src/core/tools/vimeo.rs parse_target (line 98) for the exact accepted URL shapes and match your input to one of them.

Example fix

// before
await vimeoList({ url: inputValue });
// after
const url = (inputValue ?? "").trim();
if (!/^https:\/\/vimeo\.com\/(showcase|album)\/[\w-]+/.test(url) &&
    !/^https:\/\/vimeo\.com\/channels\/[\w-]+/.test(url) &&
    !/^https:\/\/vimeo\.com\/[\w-]+$/.test(url)) {
  throw new Error("not a supported Vimeo collection URL");
}
await vimeoList({ url });
Defensive patterns

Strategy: validation

Validate before calling

const COLLECTION_RE = /^https:\/\/vimeo\.com\/(showcase\/[\w-]+|album\/[\w-]+|channels\/[\w-]+|[\w-]+)\/?$/;
function isValidVimeoCollectionUrl(u) {
  const s = (u ?? "").trim();
  return COLLECTION_RE.test(s) && !/^https:\/\/vimeo\.com\/\d+\/?$/.test(s);
}
if (!isValidVimeoCollectionUrl(opts.url)) throw new Error("invalid vimeo collection url");

Type guard

function isNonEmptyVimeoUrl(u) {
  return typeof u === "string" && u.trim().length > 0 && /vimeo\.com|\d+/.test(u.trim());
}

Try / catch

try {
  await vimeoList({ url });
} catch (e) {
  if (String(e).includes("vimeo:bad_url")) {
    showError("Please paste a Vimeo showcase/album/channel/profile URL");
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `list(opts)` with an empty `opts.url`, a non-Vimeo URL (e.g. youtube.com), a malformed Vimeo URL (e.g. `vimeo.com/showcase/` with no id), or a URL with a path segment shape parse_target does not handle.

Common situations: Users pasting a Vimeo player embed URL or an oEmbed/lti link instead of the showcase URL; frontend sending an empty url field because a form input was not bound; trailing junk or a localized Vimeo domain the parser does not recognize.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/789fd2d08d26ad31. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/vimeo.rs:852

        file,
        meta,
        tail,
        success: status.success(),
    })
}

fn secret_refs<'a>(a: Option<&'a String>, b: Option<&'a String>) -> Vec<&'a str> {
    [a, b]
        .into_iter()
        .flatten()
        .map(|s| s.as_str())
        .filter(|s| !s.trim().is_empty())
        .collect()
}

/// Enumera um showcase, álbum, canal ou perfil.
pub async fn list(opts: &ListOptions, progress: &ProgressFn) -> Result<Listing> {
    let target = parse_target(&opts.url).ok_or_else(|| anyhow!("vimeo:bad_url"))?;
    if !target.is_collection() {
        return Err(anyhow!("vimeo:not_a_collection"));
    }
    let url = target.canonical_url();
    let bin = ytdlp_bin().await?;
    let cookies = cookie_file(opts.session_netscape.as_deref());
    let used_session = cookies.is_some();
    let secrets = secret_refs(opts.showcase_password.as_ref(), None);
    let args = list_args(
        &url,
        opts.showcase_password.as_deref(),
        cookies.as_ref().map(|c| c.path.as_path()),
    );
    let command = safe_command_line("yt-dlp", &args);
    tracing::info!("[vimeo] $ {}", command);
    report(
        progress,
        ID_SHOWCASE,

View on GitHub (pinned to 8600b91f42)