tonhowtf/omniget · error

vimeo:not_a_collection

vimeo:not_a_collection

Error message

vimeo:not_a_collection

What it means

vimeo:not_a_collection is raised by `list` when the URL parses to a valid Vimeo target but that target is a single video (Target::Video), not a collection (showcase, album, channel, or user profile). `list` only enumerates multi-video containers; a single video must go through the single/private download paths instead.

Solutions

  1. Use the single-video download API (e.g. the `private`/single path) instead of `list` when the URL is a video.
  2. Confirm the URL points to a collection: it must be /showcase/<id>, /album/<id>, /channels/<name>, or /<username> — not /<numeric-id>.
  3. In the UI, detect a numeric video id first and route to single-video flow before calling list.
  4. If you truly meant to enumerate, get the showcase/album/channel URL from Vimeo and pass that.

Example fix

// before
await vimeoList({ url: "https://vimeo.com/76979871" });
// after
const m = url.match(/^https:\/\/vimeo\.com\/(\d+)(\/|$)/);
if (m) {
  await vimeoDownloadSingle({ url });
} else {
  await vimeoList({ url });
}
Defensive patterns

Strategy: validation

Validate before calling

const VIDEO_RE = /^(https:\/\/vimeo\.com\/\d+(\/[a-z0-9]+)?|\d+)$/
  .source;
function looksLikeSingleVideo(u) {
  const s = (u ?? "").trim();
  return new RegExp("^(https:\\/\\/vimeo\\.com\\/\\d+(\\/[a-z0-9]+)?|\\d+)$").test(s);
}
if (looksLikeSingleVideo(opts.url)) routeToSingleVideoApi(opts.url);

Type guard

function isCollectionUrl(u) {
  return /vimeo\.com\/(showcase|album|channels)\//.test((u ?? "").trim()) ||
    /^https:\/\/vimeo\.com\/[a-zA-Z][\w-]*$/.test((u ?? "").trim());
}

Try / catch

try {
  await vimeoList({ url });
} catch (e) {
  if (String(e).includes("vimeo:not_a_collection")) {
    showError("That is a single video; use the single-video downloader");
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `list(opts)` with `opts.url` set to a plain video link such as `https://vimeo.com/123456789`, a bare numeric id, or an unlisted link `https://vimeo.com/<id>/<hash>`.

Common situations: User pastes a normal video URL into the 'enumerate collection' feature; app routes a single-video job through the batch/backup list API by mistake; unlisted link with hash given where a showcase was expected.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

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

        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,
        "progress",
        0,

View on GitHub (pinned to 8600b91f42)