{"record":{"id":"4ab5edf068a486bd","repo":"GitoxideLabs/gitoxide","slug":"bug-in-lookup-symbol-has-path-must-return-lookup","errorCode":null,"errorMessage":"Bug in lookup_symbol_has_path - must return lookup symbols","messagePattern":"Bug in lookup_symbol_has_path - must return lookup symbols","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-protocol/src/handshake/refs/shared.rs","lineNumber":188,"sourceCode":"                    let id = gix_hash::ObjectId::from_hex(path)?;\n                    out_shallow.push(ShallowUpdate::Shallow(id));\n                    return Ok(());\n                }\n                Err(err) => return Err(err.into()),\n            };\n            match out_refs\n                .iter()\n                .take(num_initial_out_refs)\n                .position(|r| r.lookup_symbol_has_path(path.into()))\n            {\n                Some(position) => match out_refs.swap_remove(position) {\n                    InternalRef::SymbolicForLookup { path: _, target } => out_refs.push(InternalRef::Symbolic {\n                        path: path.into(),\n                        tag: None, // TODO: figure out how annotated tags work here.\n                        object,\n                        target,\n                    }),\n                    _ => unreachable!(\"Bug in lookup_symbol_has_path - must return lookup symbols\"),\n                },\n                None => out_refs.push(InternalRef::Direct {\n                    object,\n                    path: path.into(),\n                }),\n            }\n        }\n    }\n    Ok(())\n}\n\npub(in crate::handshake::refs) fn parse_v2(line: &BStr) -> Result<Ref, Error> {\n    let trimmed = line.trim_end();\n    let mut tokens = trimmed.splitn(4, |b| *b == b' ');\n    match (tokens.next(), tokens.next()) {\n        (Some(hex_hash), Some(path)) => {\n            let id = if hex_hash == b\"unborn\" {\n                None","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-protocol/src/handshake/refs/shared.rs#L170-L206","documentation":"An `unreachable!()` panic in `gix_protocol::handshake::refs::shared::parse_v1` when parsing a v1 ref advertisement. The code expects that whenever a symbolic-ref lookup matched (`lookup_symbol_has_path`), the matched internal ref is `SymbolicForLookup`; any other variant reaching that arm triggers the panic, flagging a bug in the match predicate.","triggerScenarios":"Performing a protocol v1 handshake (e.g. clone/fetch over a transport that negotiates v1) where the ref-name matching logic returns a hit whose internal ref variant is not `SymbolicForLookup` — possible with remotes advertising refs like `HEAD` plus similarly-named refs that confuse the matcher, indicating a gix bug.","commonSituations":"Cloning from older or non-standard Git servers (git-daemon, custom implementations, older GitLab/Gitea versions) that use protocol v1 and advertise symbolic refs inconsistently; mostly encountered as an upstream bug report.","solutions":["Force protocol v2 (`GIT_PROTOCOL=version=2` equivalent in gix transport config) or use a transport/server combination that negotiates v2 and retry","Upgrade gix / gix-protocol to the newest release; the panic marks a matcher bug to report upstream with the remote URL","Work around by mirroring the remote with real `git clone` first and fetching from the local mirror"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"std::panic::catch_unwind(|| parse_v1_refs(advertisement))\n    .map_err(|_| \"protocol v1 ref parse failed; retry with protocol v2\")?","preventionTips":["Prefer protocol v2 (`git clone` defaults to it) to avoid v1 parsing paths","Test clones against your server fleet with gix before rolling out automation","Keep gix-protocol current — v1 matcher bugs are patched upstream","Mirror problem servers with real git and read from the local mirror instead"],"tags":["rust","panic","handshake","protocol-v1","refs"],"backgroundTag":"internal-invariant-violation","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}