{"record":{"id":"bf5f7e81c5ac8b8e","repo":"astrid-runtime/astrid","slug":"winfsp-service-parent-start-identity-is-required-o","errorCode":null,"errorMessage":"WinFsp service parent start identity is required on Windows","messagePattern":"WinFsp service parent start identity is required on Windows","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-winfsp/src/win.rs","lineNumber":255,"sourceCode":"    if launch.schema != STORAGE_FILESYSTEM_SERVICE_LAUNCH_SCHEMA_V1 {\n        bail!(\"unsupported WinFsp service launch schema {}\", launch.schema);\n    }\n    if launch.parent.pid <= 1 || launch.parent.pid == std::process::id() {\n        bail!(\"WinFsp service parent PID is invalid\");\n    }\n    if launch.parent.token.len() < 16\n        || launch.parent.token.len() > 512\n        || launch.parent.token.chars().any(char::is_control)\n    {\n        bail!(\"WinFsp service parent token is invalid\");\n    }\n    if let Some(identity) = launch.parent.start_identity.as_deref()\n        && (identity.is_empty() || identity.len() > 512 || identity.chars().any(char::is_control))\n    {\n        bail!(\"WinFsp service parent start identity is invalid\");\n    }\n    if launch.parent.start_identity.is_none() {\n        bail!(\"WinFsp service parent start identity is required on Windows\");\n    }\n    let lease = &launch.lease;\n    let now = SystemTime::now()\n        .duration_since(UNIX_EPOCH)\n        .context(\"read system clock\")?\n        .as_secs();\n    if lease.expires_at_epoch_secs < now {\n        bail!(\"WinFsp lease is expired\");\n    }\n    if lease.lease_token.len() < 16 || lease.lease_token.len() > 4096 {\n        bail!(\"WinFsp lease callback token is invalid\");\n    }\n    if !lease.resource_path.is_absolute()\n        || !lease.callback_path.is_absolute()\n        || lease.callback_path != lease.resource_path.join(\"control.endpoint\")\n    {\n        bail!(\"WinFsp lease paths are malformed\");\n    }","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-winfsp/src/win.rs#L237-L273","documentation":"On Windows this provider requires the launching parent to declare a start_identity in the service launch descriptor. If launch.parent.start_identity is None (the field was omitted or explicitly null), validate_service_launch bails before any mount work. The identity anchors the mount to the principal that started it, so an absent value means the launch cannot be attributed and is rejected by design.","triggerScenarios":"service_main -> validate_service_launch with launch.parent.start_identity == None: the parent process built StorageProviderServiceLaunchV1 without populating parent.start_identity, or deserialized a launch JSON that omits/nulls the field.","commonSituations":"A launcher written against an older schema version (before start_identity became required on Windows) still emits old launch files; hand-written or copied launch JSON omits the field; shared cross-platform launcher code sets the field only on non-Windows targets.","solutions":["Populate parent.start_identity in the launching parent before spawning service_main (e.g. the owning user/account or session identifier).","Check the deserialization of the launch JSON on the service side — make sure the field is present and not null; a field silently defaulting to None usually means the key is missing in the file.","If this appears after a provider upgrade, regenerate the launch descriptor with the current launcher instead of reusing a cached/older one.","Guard shared launcher code so the Windows path always sets start_identity (cfg-gate if other platforms treat it as optional)."],"exampleFix":"// before\nlet launch = StorageProviderServiceLaunchV1 { parent: Parent { pid, token, ..Default::default() }, .. };\n// after\nlet launch = StorageProviderServiceLaunchV1 { parent: Parent { pid, token, start_identity: Some(whoami_identity()), .. }, .. };","handlingStrategy":"validation","validationCode":"if launch.parent.start_identity.is_none() {\n    return Err(anyhow!(\"launch descriptor must set parent.start_identity before starting the Windows service\"));\n}","typeGuard":"fn has_start_identity(p: &Parent) -> bool { p.start_identity.as_deref().map_or(false, |s| !s.is_empty()) }","tryCatchPattern":null,"preventionTips":["Always set start_identity in the Windows launch path; make it a constructor argument, not an Option default","Regenerate launch descriptors after provider upgrades instead of replaying cached ones","Add a serde deny_unknown_fields/required-field test for launch JSON round-trips","cfg-gate cross-platform launcher code so Windows builds fail at compile time if identity is not supplied"],"tags":["winfsp","windows","missing-field","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}