{"record":{"id":"8e7a1e163d292325","repo":"astrid-runtime/astrid","slug":"invalid-parent-token","errorCode":null,"errorMessage":"invalid parent token","messagePattern":"invalid parent token","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fskit/src/service.rs","lineNumber":405,"sourceCode":"\n    let info = pidinfo::<BSDInfo>(i32::try_from(pid).ok()?, 0).ok()?;\n    Some(format!(\n        \"{}:{}\",\n        info.pbi_start_tvsec, info.pbi_start_tvusec\n    ))\n}\n\nfn validate_launch_parent(\n    parent: &astrid_core::storage_filesystem::StorageProviderParentLifetimeV1,\n) -> Result<()> {\n    if parent.pid <= 1 || parent.pid == std::process::id() {\n        bail!(\"invalid parent PID\");\n    }\n    if parent.token.len() < 16\n        || parent.token.len() > 512\n        || parent.token.chars().any(char::is_control)\n    {\n        bail!(\"invalid parent token\");\n    }\n    if let Some(identity) = parent.start_identity.as_deref()\n        && (identity.is_empty() || identity.len() > 512 || identity.chars().any(char::is_control))\n    {\n        bail!(\"invalid parent start identity\");\n    }\n    #[cfg(any(target_os = \"linux\", target_os = \"macos\"))]\n    if parent.start_identity.is_none() {\n        bail!(\"parent start identity is required on this platform\");\n    }\n    Ok(())\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[cfg(target_os = \"macos\")]","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fskit/src/service.rs#L387-L423","documentation":"validate_launch_parent also validates the parent's lifetime token: it must be 16–512 bytes and contain no control characters. The token identifies the parent's lifetime for supervision; an empty, oversized, or control-character-laden token is treated as malformed and rejected.","triggerScenarios":"validate_launch_parent receives StorageProviderParentLifetimeV1 whose token is shorter than 16 bytes, longer than 512 bytes, or contains control characters (e.g. embedded \\0 or \\n) — typically a truncated, placeholder, or raw-binary token.","commonSituations":"Passing an empty/placeholder token in tests or config; generating the token as raw bytes instead of a hex/base64 string; copying a token with a trailing newline.","solutions":["Generate a token of 16–512 printable characters (e.g. 32-char random hex/base64)","Trim/strip control characters and newlines from the token before sending","Check where the token is produced and ensure it isn't truncated or left as a default empty string","Validate the token length client-side before constructing the launch request"],"exampleFix":"// before\nlet token = format!(\"{}\\n\", raw_bytes); // control chars, maybe <16 bytes\n// after\nlet token = base64::encode(rand::random::<[u8; 32]>()); // 44 printable chars","handlingStrategy":"validation","validationCode":"fn parent_token_ok(t: &str) -> bool { (16..=512).contains(&t.len()) && !t.chars().any(char::is_control) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate tokens as 16–512 printable chars (e.g. 32-byte hex/base64)","Trim whitespace/newlines from tokens","Never ship empty or placeholder tokens in config or tests","Validate tokens at construction time"],"tags":["validation","security","token"],"backgroundTag":"invalid-argument-value","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}