astrid-runtime/astrid · error
invalid --egress entry
Error message
invalid --egress entry {entry:?}: {e} What it means
Raised in build_caps_to_grant when a single --egress entry cannot be validated by astrid_core::capability_grammar::validate_capability after being formatted as 'network:egress:{entry}'. The grammar validator rejects entries that do not form a syntactically valid egress capability token.
Solutions
- Fix the offending --egress entry so it matches the capability grammar (valid domain/host form)
- Check the error suffix from validate_capability, which names the exact grammar violation
- Split multiple targets with commas and trim whitespace; quote the argument in the shell
Example fix
// before --egress 'example .com,api.example.org' // after --egress 'example.com,api.example.org'
Defensive patterns
Strategy: validation
Validate before calling
let cap = format!("network:egress:{entry}");
if astrid_core::capability_grammar::validate_capability(&cap).is_err() { eprintln!("invalid egress entry: {entry}"); std::process::exit(2); } Type guard
fn valid_egress(entry: &str) -> bool { astrid_core::capability_grammar::validate_capability(&format!("network:egress:{entry}")).is_ok() } Try / catch
match build_caps_to_grant(&args) { Ok(caps) => caps, Err(e) => { eprintln!("{e:#}"); std::process::exit(2); } } Prevention
- Keep each comma-separated egress entry to a bare host/domain form
- Trim whitespace and avoid stray characters when composing --egress
- Test new capability strings against validate_capability in a unit test
When it happens
Trigger: Calling run_create with --egress containing an entry that produces an invalid capability string, e.g. empty after comma-splitting is filtered (rare), entries with illegal characters, spaces, wildcards, or a malformed domain/port specification.
Common situations: Typing a domain with a trailing comma issue, including spaces inside an entry ('example .com'), using shell-glob wildcards where the grammar forbids them, or pasting a full capability string when only the egress target is expected.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid --process-allow entry
- byte value must be non-negative and finite
- capsule ' ': branch/rev require building from source and…
- capsule name ' ' is invalid (must match ^[a-z][a-z0-9-]*$)
- capsule ' ': tag must not be empty
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/d67c8e96f3ea0e71.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/commands/agent/mod.rs:440
if let Some(n) = args.processes {
updates.push(QuotaField::Processes(n));
}
Ok(updates)
}
/// Translate `--egress` / `--process-allow` allow-lists into Layer 6
/// capability patterns and validate each against the capability
/// grammar (no dots in segments, etc.). Catching invalid labels here
/// — before any IPC — prevents the kernel from accepting the agent
/// profile and then rejecting the follow-up grant, which would leave a
/// half-provisioned agent on disk.
fn build_caps_to_grant(args: &CreateArgs) -> Result<Vec<String>> {
let mut caps: Vec<String> = Vec::new();
if let Some(domains) = args.egress.as_deref() {
for entry in domains.split(',').map(str::trim).filter(|s| !s.is_empty()) {
let cap = format!("network:egress:{entry}");
astrid_core::capability_grammar::validate_capability(&cap)
.map_err(|e| anyhow::anyhow!("invalid --egress entry {entry:?}: {e}"))?;
caps.push(cap);
}
}
if let Some(cmds) = args.process_allow.as_deref() {
for entry in cmds.split(',').map(str::trim).filter(|s| !s.is_empty()) {
let cap = format!("process:spawn:{entry}");
astrid_core::capability_grammar::validate_capability(&cap)
.map_err(|e| anyhow::anyhow!("invalid --process-allow entry {entry:?}: {e}"))?;
caps.push(cap);
}
}
Ok(caps)
}
/// Apply the parsed quota deltas: `QuotaGet` to pull the new agent's
/// defaults, replay each requested field, single `QuotaSet`. A failure
/// here leaves the agent in place with default quotas — operator can
/// re-run `astrid quota set -a <name> ...` to retry.View on GitHub (pinned to affd8760f4)