astrid-runtime/astrid · error

--scope requires the capsule manifest to declare '{key}' as

Error message

--scope requires the capsule manifest to declare '{key}' as type="secret" (manifest declares either a non-secret env field, or no field at all for this key)

What it means

`run_set` enforces that `--scope` (agent vs shared storage) can only be used when the capsule manifest declares the key as `type="secret"`. It resolves the key's kind from the daemon's capsule metadata; if the manifest declares the field as plain text, or has no field for that key at all, passing `--scope` bails with this error.

Source

Thrown at crates/astrid-cli/src/commands/secret.rs:307

        }))
}

async fn run_set(args: &SetArgs) -> Result<ExitCode> {
    if args.key.is_empty() {
        anyhow::bail!("invalid key: must not be empty");
    }
    let principal = context::resolve_agent(args.agent.as_deref())?;
    let capsule = validate_optional_capsule(args.capsule.as_deref())?;

    // --scope only applies to secrets. Resolve the type from the daemon's
    // durable registry rather than reading a native principal-home manifest.
    let kind = capsule_env_kind(&capsule, &args.key)
        .await?
        .unwrap_or(EnvValueKind::Text);
    let secret_declared = kind == EnvValueKind::Secret;

    if args.scope.is_some() && !secret_declared {
        anyhow::bail!(
            "--scope requires the capsule manifest to declare '{}' as type=\"secret\" \
             (manifest declares either a non-secret env field, or no field at all for this key)",
            args.key
        );
    }

    let scope = args
        .scope
        .map_or(EnvStorageScope::Agent, |scope| match scope {
            ScopeArg::Agent => EnvStorageScope::Agent,
            ScopeArg::Shared => EnvStorageScope::Shared,
        });
    if matches!(kind, EnvValueKind::Text) && !matches!(scope, EnvStorageScope::Agent) {
        anyhow::bail!("--scope=shared is only valid for manifest-declared secrets");
    }
    let mut client = crate::admin_client::connect_as_active_agent().await?;
    let body = client
        .request(AdminRequestKind::EnvSet {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Add `type = "secret"` to the env entry for this key in the capsule manifest and redeploy/reload the capsule.
  2. Drop the `--scope` flag if the value is genuinely a plain text env var.
  3. Fix the key spelling so it matches the manifest entry declared as a secret.
  4. Run the set without --scope first and check `astrid secret list` to see how the key is classified.

Example fix

// before (capsule manifest)
[env]
API_KEY = { value = "placeholder" }
// after
[env]
API_KEY = { value = "placeholder", type = "secret" }
Defensive patterns

Strategy: validation

Validate before calling

// inspect the capsule manifest before using --scope
grep -A3 "${KEY}" capsule.toml  # entry must include type = "secret"

Try / catch

// run_set pattern
if args.scope.is_some() && !secret_declared {
    eprintln!("hint: declare {key} as type=\"secret\" in the capsule manifest, or omit --scope");
}

Prevention

When it happens

Trigger: `astrid secret set --scope agent|shared --key FOO` where the capsule's manifest either omits FOO from its env section or declares it without `type = "secret"`.

Common situations: Typo in the key name so it doesn't match the manifest entry; manifest env field declared as plain text (no type="secret"); user assumes any value can be stored shared; manifest not yet reloaded by the daemon after editing.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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