astrid-runtime/astrid · error

invalid parent start identity

Error message

invalid parent start identity

What it means

The optional start_identity field of the parent lifetime record, when present, must be a non-empty string of at most 512 bytes with no control characters. An identity that is empty, too long, or contains control characters is rejected as malformed.

Solutions

  1. If no start identity applies, pass None instead of Some(empty string)
  2. Trim the identity string and remove control characters before constructing the record
  3. Keep the identity a short, printable identifier (<= 512 bytes)
  4. Validate the identity string at the point of construction

Example fix

// before
start_identity: Some(String::new())
// after
start_identity: (identity.is_empty() { None } else { Some(identity.trim().to_string()) })
Defensive patterns

Strategy: validation

Validate before calling

fn start_identity_ok(id: &Option<String>) -> bool { id.as_deref().map_or(true, |s| !s.is_empty() && s.len() <= 512 && !s.chars().any(char::is_control)) }

Prevention

When it happens

Trigger: validate_launch_parent sees parent.start_identity = Some(s) where s.is_empty(), s.len() > 512, or s contains control characters — e.g. Some("") used as a placeholder instead of None.

Common situations: Code defaulting to Some(String::new()) instead of None; embedding the identity with a trailing newline; very long bundle/exec identifiers pasting in full paths with control bytes.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-storage-provider-fskit/src/service.rs:410

    ))
}

fn validate_launch_parent(
    parent: &astrid_core::storage_filesystem::StorageProviderParentLifetimeV1,
) -> Result<()> {
    if parent.pid <= 1 || parent.pid == std::process::id() {
        bail!("invalid parent PID");
    }
    if parent.token.len() < 16
        || parent.token.len() > 512
        || parent.token.chars().any(char::is_control)
    {
        bail!("invalid parent token");
    }
    if let Some(identity) = parent.start_identity.as_deref()
        && (identity.is_empty() || identity.len() > 512 || identity.chars().any(char::is_control))
    {
        bail!("invalid parent start identity");
    }
    #[cfg(any(target_os = "linux", target_os = "macos"))]
    if parent.start_identity.is_none() {
        bail!("parent start identity is required on this platform");
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[cfg(target_os = "macos")]
    #[test]
    #[ignore = "requires an explicit disposable live FSKit lease manifest"]
    fn live_managed_callback_lease_is_accepted() {
        let path = std::env::var("ASTRID_FSKIT_TEST_LEASE_MANIFEST").expect("explicit QA manifest");
        let bytes = std::fs::read(path).expect("read QA manifest");

View on GitHub (pinned to affd8760f4)