{"record":{"id":"a227ff089b8bcba4","repo":"tonhowtf/omniget","slug":"target-domain-is-required-for-cookie-header-import","errorCode":null,"errorMessage":"Target domain is required for Cookie header import.","messagePattern":"Target domain is required for Cookie header import\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/src/cookies/parsers.rs","lineNumber":98,"sourceCode":"        };\n        let name = name.trim();\n        if name.is_empty() || value.is_empty() || !is_cookie_name(name) {\n            return false;\n        }\n        found += 1;\n    }\n    found > 0\n}\n\nfn is_cookie_name(name: &str) -> bool {\n    name.bytes()\n        .all(|b| b.is_ascii_alphanumeric() || matches!(b, b'_' | b'-' | b'.'))\n}\n\npub fn parse_cookie_header(content: &str, domain: &str) -> anyhow::Result<Vec<ExtensionCookie>> {\n    let root = domain.trim().trim_start_matches('.').to_lowercase();\n    if root.is_empty() {\n        anyhow::bail!(\"Target domain is required for Cookie header import.\");\n    }\n    let cookie_domain = format!(\".{}\", root);\n    let expires = std::time::SystemTime::now()\n        .duration_since(std::time::UNIX_EPOCH)\n        .map(|d| d.as_secs() as i64)\n        .unwrap_or(0)\n        + 60 * 60 * 24 * 3;\n    let body = content\n        .trim()\n        .strip_prefix(\"Cookie:\")\n        .unwrap_or(content.trim());\n    let mut cookies = Vec::new();\n    for part in body.split(';') {\n        let p = part.trim();\n        if p.is_empty() {\n            continue;\n        }\n        let Some((name, value)) = p.split_once('=') else {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/src/cookies/parsers.rs#L80-L116","documentation":"parse_cookie_header() requires a target domain to scope the imported cookies (it builds '.{root}' as the cookie domain). An empty or whitespace-only domain (after trimming and stripping a leading dot) bails with this message.","triggerScenarios":"Calling parse_for_domain/parse_cookie_header with domain = \"\", \"   \", or \".\" so root becomes empty.","commonSituations":"UI passes an unset/blank domain field; config lookup for the domain returns empty string; caller forgets the domain argument when importing header-style cookies.","solutions":["Pass a non-empty target domain, e.g. parse_cookie_header(content, \"bilibili.com\").","Validate/trim the domain input in the caller before invoking the parser.","Use parse() for Netscape/JSON content, which does not need a domain."],"exampleFix":"// before\nparse_cookie_header(\"a=b\", \"\")?;\n// after\nlet domain = domain.trim();\nanyhow::ensure!(!domain.is_empty(), \"domain required\");\nparse_cookie_header(\"a=b\", domain)?;","handlingStrategy":"validation","validationCode":"let domain = domain.trim().trim_start_matches('.');\nanyhow::ensure!(!domain.is_empty(), \"Target domain is required for Cookie header import.\");","typeGuard":null,"tryCatchPattern":"match parsers::parse_for_domain(content, &domain) {\n    Err(e) if e.to_string().contains(\"Target domain is required\") => prompt_for_domain(),\n    other => other,\n}","preventionTips":["Always supply the site hostname when importing header-style cookies","Validate the domain field in the UI before submitting","Fall back to parse() for Netscape/JSON which need no domain"],"tags":["cookies","domain","validation","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}