astrid-runtime/astrid · error

--grant-capsules is not supported for .shuttle installs yet

Error message

--grant-capsules is not supported for .shuttle installs yet — install first, then grant with `astrid --principal {operator} agent modify {target} --add-capsule <name>` for each installed capsule.

What it means

validate_install_source rejects combining --grant-capsules with a .shuttle distro source. Capsule granting is not wired up for .shuttle archives, so the CLI fails loudly instead of silently skipping the requested grants, and points the user at the legacy manual grant command.

Source

Thrown at crates/astrid-cli/src/commands/init.rs:93

            bail!("--var has an empty key (got {item:?})");
        }
        map.insert(key.to_string(), value.to_string());
    }
    Ok(map)
}

/// Enforce source flags before this flow can create runtime state.
fn validate_install_source(
    distro_source: &str,
    opts: &InitOpts,
    operator: &astrid_core::PrincipalId,
    target: &astrid_core::PrincipalId,
) -> anyhow::Result<bool> {
    let shuttle_install = distro_source.ends_with(".shuttle");
    // `--grant-capsules` is not wired for `.shuttle`; fail rather than silently
    // skip the requested grants and point at the legacy manual command.
    if shuttle_install && opts.grant_capsules {
        bail!(
            "--grant-capsules is not supported for .shuttle installs yet — \
             install first, then grant with `astrid --principal {operator} \
             agent modify {target} \
             --add-capsule <name>` for each installed capsule."
        );
    }
    Ok(shuttle_install)
}

/// Run the init flow: workspace setup + distro-based capsule installation.
pub(crate) async fn run_init(distro_source: &str, opts: &InitOpts) -> anyhow::Result<()> {
    let home = AstridHome::resolve()?;
    let operator = crate::principal::current();
    let target = opts.target_principal.clone();

    // `--grant-capsules` is only meaningful when a distro install is
    // resolving the capsule set to grant. Reject an empty source up front so
    // the flag can never be silently honoured without a distro.

View on GitHub (pinned to affd8760f4)

Solutions

  1. Drop --grant-capsules from the .shuttle install command.
  2. After the install completes, grant per capsule with: astrid --principal {operator} agent modify {target} --add-capsule <name>.
  3. Alternatively use a non-.shuttle source (e.g. @owner/repo) if you need automatic capsule granting.

Example fix

// before
astrid init @acme/distro --shuttle --grant-capsules
// after
astrid init @acme/distro --shuttle
astrid --principal <operator> agent modify <target> --add-capsule <name>
Defensive patterns

Strategy: validation

Validate before calling

if source.ends_with(".shuttle") && grant_capsules {
    eprintln!("--grant-capsules is unsupported for .shuttle installs");
    std::process::exit(2);
}

Try / catch

match validate_install_source(source, &opts, target) {
    Ok(granted) => proceed(granted),
    Err(e) => eprintln!("{e:#}"),
}

Prevention

When it happens

Trigger: Running init with a distro source ending in '.shuttle' while opts.grant_capsules is true (i.e. --grant-capsules was passed).

Common situations: Automating installs from a self-contained .shuttle archive and passing --grant-capsules out of habit from GitHub-sourced distros; CI scripts that always include --grant-capsules.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/9b9f37304a0e8dc4. Report an issue: GitHub.