{"record":{"id":"31388be955656f76","repo":"astrid-runtime/astrid","slug":"grant-capsules-requires-a-resolved-distro-grant","errorCode":null,"errorMessage":"--grant-capsules requires a resolved distro: grants apply to the capsules a distro installs","messagePattern":"--grant-capsules requires a resolved distro: grants apply to the capsules a distro installs","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/init_grant.rs","lineNumber":54,"sourceCode":"        newly_installed.to_vec()\n    }\n}\n\n/// Guard: `--grant-capsules` may only be honoured alongside a distro\n/// install, because the grant set is exactly the capsules that distro\n/// installs. `distro_present` is whether a non-empty distro source\n/// resolved. Pure so the invariant is unit-testable without a network\n/// install.\n///\n/// # Errors\n/// Returns an error when `grant_capsules` is set but no distro source is\n/// present.\npub(super) fn validate_grant_capsules(\n    grant_capsules: bool,\n    distro_present: bool,\n) -> anyhow::Result<()> {\n    if grant_capsules && !distro_present {\n        bail!(\n            \"--grant-capsules requires a resolved distro: grants apply to the capsules a distro installs\"\n        );\n    }\n    Ok(())\n}\n\n/// Complete the mandatory second Distro Apply stage for the authenticated\n/// caller. The kernel derives both target and member set from its admitted\n/// lock; no capsule names cross this boundary.\npub(crate) async fn apply_self_grant(caller: &PrincipalId) -> anyhow::Result<()> {\n    eprintln!(\n        \"{}\",\n        Theme::info(&format!(\"Granting Distro capsule access to '{caller}'...\"))\n    );\n    let mut client = crate::admin_client::connect_for_workspace_as(caller.clone())\n        .await\n        .context(\"Distro install committed, but connecting for the self grant failed\")?;\n    let body = client","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/init_grant.rs#L36-L72","documentation":"validate_grant_capsules enforces that the --grant-capsules flag is only used together with a resolved distro, because grants are computed from the capsules a distro installs. Passing --grant-capsules during init without a distro is rejected with this bail.","triggerScenarios":"Running `init --grant-capsules ...` when no distro was resolved/present in the init context (distro_present == false).","commonSituations":"A user copies an init command from docs that includes --grant-capsules but forgets the distro argument/URL; a script builds the command conditionally and the distro portion was dropped.","solutions":["Add the distro argument (or select a distro) so init resolves one before applying --grant-capsules.","Remove --grant-capsules if no distro install is intended and grant capsules explicitly by other means.","Fix the wrapper script so the flag is only emitted when a distro is present."],"exampleFix":"// before\nastrid init --grant-capsules            # no distro\n// after\nastrid init --distro my-distro --grant-capsules","handlingStrategy":"validation","validationCode":"// shell pre-check before invoking init\nif [[ \" $args \" == *\" --grant-capsules \"* && -z \"$DISTRO\" ]]; then\n  echo \"--grant-capsules requires --distro\"; exit 2;\nfi","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"--grant-capsules requires a resolved distro\") => eprintln!(\"add a --distro argument or drop --grant-capsules\"),\n    Err(e) => return Err(e),\n    Ok(v) => Ok(v),\n}","preventionTips":["Only emit --grant-capsules in scripts when a distro is being resolved.","Document that the flag depends on a distro install.","Use CLI wrappers that validate flag combinations before exec."],"tags":["cli","flag-misuse","validation"],"backgroundTag":"missing-required-flag","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}