astrid-runtime/astrid · error
seal can only resolve GitHub-backed capsule sources (@org/re
Error message
seal can only resolve GitHub-backed capsule sources (@org/repo); got {source:?} What it means
`seal` (capsule installation) resolves capsule sources exclusively from GitHub repositories in `@org/repo` form. `resolve_capsule_to_file` throws this error when `parse_github_source` cannot extract an org/repo pair from the given source string, e.g. when a local path, bare name, URL, or other registry scheme is passed.
Source
Thrown at crates/astrid-cli/src/commands/capsule/install.rs:421
/// release assets, so a missing asset is a hard error the maintainer
/// must resolve.
/// `name_hint` is the distro capsule `name`, used to pick the right
/// archive when one source ships several (a monorepo builds/releases one
/// `.capsule` per capsule crate) — the same `capsule_assets`/`pick_capsule`
/// selection [`install_from_github`] uses. A single-asset release installs
/// that one regardless of the hint.
/// The returned ref is the single source of truth the seal records in
/// the lock's `resolved_ref`: it is whatever GitHub reported as the
/// release `tag_name`, never an optimistic guess from the manifest.
pub(crate) async fn resolve_capsule_to_file(
source: &str,
version: Option<&str>,
tag: Option<&str>,
name_hint: Option<&str>,
dest_path: &Path,
) -> anyhow::Result<String> {
let (org, repo) = parse_github_source(source).ok_or_else(|| {
anyhow::anyhow!(
"seal can only resolve GitHub-backed capsule sources (@org/repo); got {source:?}"
)
})?;
// Authenticated when a token is present (see `github_api_client`).
let client = github_api_client()?;
let resolved_ref = resolve_github_ref(&client, &org, &repo, version, tag).await?;
// Fetch the resolved release's assets and pick the right `<name>.capsule`
// (the same selection the install path uses), so a release shipping
// several capsules downloads the one the seal asked for rather than the
// first. A missing `.capsule` asset is a hard error — seal requires
// pre-built release artifacts.
let api_url = release_tag_url(&org, &repo, &resolved_ref)?;
let response = client
.get(&api_url)
.send()View on GitHub (pinned to affd8760f4)
Solutions
- Use the `@org/repo` form for the source, e.g. `@acme/my-capsule`
- If installing from a local file, use the local-path install path instead of `seal`'s GitHub resolver
- Check for typos: exactly one `@` at the start and exactly one `/` separating org and repo
Example fix
// before seal --source my-capsule // after seal --source @acme/my-capsule
Defensive patterns
Strategy: validation
Validate before calling
fn is_github_source(source: &str) -> bool {
let rest = source.strip_prefix('@')?;
let (org, repo) = rest.split_once('/')?;
Some(()).filter(|_| !org.is_empty() && !repo.is_empty() && !repo.contains('/')).is_some()
}
if !is_github_source(source) { /* fix or route to local installer */ } Type guard
fn as_github_source(source: &str) -> Option<(&str, &str)> {
let rest = source.strip_prefix('@')?;
let (org, repo) = rest.split_once('/')?;
(!org.is_empty() && !repo.is_empty() && !repo.contains('/')).then(|| (org, repo))
} Prevention
- Always write sources in @org/repo shorthand
- Use local-path install commands for locally built capsules
- Validate the source string in wrapper scripts before invoking seal
When it happens
Trigger: Calling `resolve_capsule_to_file` (via `stage_capsule`) with a source that is not `@org/repo`: a local file path, an https:// URL, a bare capsule name without the `@` prefix, or a malformed ref like `@org` or `org/repo` (missing `@`).
Common situations: Typing the capsule name without the `@org/` prefix; pointing seal at a locally-built capsule archive instead of a GitHub release; pasting a full GitHub URL instead of the shorthand; typos like `@org/repo/extra`.
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
- release {resolved_ref} of {org}/{repo} ships no .capsule ass
- failed to install {} capsule(s): {names}
- --var names no [env] field in {capsule_id}: {key}
- --var names no [env] field in {capsule_id}: {key}
- Capsule '{name}' is not installed.
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/b5a864672c6cae80.
Report an issue: GitHub.