{"record":{"id":"fc9623fa87001609","repo":"xai-org/x-algorithm","slug":"env-cache-warm-sample-pct-error","errorCode":null,"errorMessage":"{ENV_CACHE_WARM_SAMPLE_PCT}: {error}","messagePattern":"\\{ENV_CACHE_WARM_SAMPLE_PCT\\}: \\{error\\}","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"visibility-filtering/config.rs","lineNumber":60,"sourceCode":"pub fn fallback_cache_serve_stale_enabled() -> bool {\n    parse_env_flag(\n        std::env::var(ENV_FALLBACK_CACHE_SERVE_STALE_ENABLED)\n            .ok()\n            .as_deref(),\n    )\n}\n\npub fn fallback_cache_populate_enabled() -> bool {\n    parse_env_flag(\n        std::env::var(ENV_FALLBACK_CACHE_POPULATE_ENABLED)\n            .ok()\n            .as_deref(),\n    )\n}\n\npub fn cache_warm_sample_pct() -> u8 {\n    parse_sample_pct(std::env::var(ENV_CACHE_WARM_SAMPLE_PCT).ok().as_deref())\n        .unwrap_or_else(|error| panic!(\"{ENV_CACHE_WARM_SAMPLE_PCT}: {error}\"))\n}\n\nfn parse_sample_pct(value: Option<&str>) -> Result<u8, String> {\n    let Some(value) = value.map(str::trim).filter(|v| !v.is_empty()) else {\n        return Ok(0);\n    };\n    match value.parse::<u8>() {\n        Ok(pct) if pct <= 100 => Ok(pct),\n        _ => Err(format!(\"expected an integer 0-100, got {value:?}\")),\n    }\n}\n\nfn parse_env_flag(value: Option<&str>) -> bool {\n    value.is_some_and(|value| {\n        matches!(\n            value.to_ascii_lowercase().as_str(),\n            \"1\" | \"true\" | \"yes\" | \"on\"\n        )","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/visibility-filtering/config.rs#L42-L78","documentation":"The VF cache warm sampling percentage is read from the environment variable named by ENV_CACHE_WARM_SAMPLE_PCT and parsed by parse_sample_pct; a present-but-malformed value (not 0-100, non-numeric, negative) causes this panic with the variable name and the parse error. An unset or empty value safely defaults to 0.","triggerScenarios":"Setting the cache warm sample pct env var to something like 'abc', '150', '-1', '1.5', or '50%' — any string parse_sample_pct rejects. Startup then panics inside cache_warm_sample_pct().","commonSituations":"Typos in deployment env files, percentage written with a '%' suffix, decimal values where u8 integer is expected, copying a value from another environment with different constraints.","solutions":["Set the variable to an integer between 0 and 100 (e.g. VF_CACHE_WARM_SAMPLE_PCT=10), or unset it entirely to default to 0.","Check for stray whitespace/quotes/% signs in the env var value in your deployment manifest.","If you control the crate, replace the panic with a logged warning and fallback to 0 for resilience."],"exampleFix":"// before\npub fn cache_warm_sample_pct() -> u8 {\n    parse_sample_pct(std::env::var(ENV_CACHE_WARM_SAMPLE_PCT).ok().as_deref())\n        .unwrap_or_else(|error| panic!(\"{ENV_CACHE_WARM_SAMPLE_PCT}: {error}\"))\n}\n\n// after\npub fn cache_warm_sample_pct() -> u8 {\n    parse_sample_pct(std::env::var(ENV_CACHE_WARM_SAMPLE_PCT).ok().as_deref())\n        .unwrap_or_else(|error| {\n            tracing::warn!(\"invalid {ENV_CACHE_WARM_SAMPLE_PCT}: {error}; defaulting to 0\");\n            0\n        })\n}","handlingStrategy":"validation","validationCode":"fn valid_sample_pct() -> Result<u8, String> {\n    match std::env::var(\"VF_CACHE_WARM_SAMPLE_PCT\") {\n        Ok(v) if v.trim().is_empty() => Ok(0),\n        Ok(v) => v.trim().parse::<u8>().ok()\n            .filter(|p| *p <= 100)\n            .ok_or_else(|| format!(\"bad pct: {v}\")),\n        Err(_) => Ok(0),\n    }\n}\n// run before calling cache_warm_sample_pct()","typeGuard":"fn is_valid_pct(s: &str) -> bool {\n    s.trim().parse::<u8>().map(|v| v <= 100).unwrap_or(false)\n}","tryCatchPattern":"let pct = std::panic::catch_unwind(cache_warm_sample_pct)\n    .unwrap_or_else(|_| { log::warn!(\"invalid pct env; using 0\"); 0 });","preventionTips":["Validate env vars in a startup config check that reports all problems at once.","Use integers 0-100 without '%' suffix; document allowed range next to the var name.","Prefer fail-fast config validation with clear messages over deep runtime panics.","Lint deployment manifests for numeric env var formatting."],"tags":["rust","env-var","configuration","startup","panic","visibility-filtering"],"backgroundTag":"invalid-env-var-value","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}