{"record":{"id":"88a2a88c4bf141aa","repo":"GitoxideLabs/gitoxide","slug":"could-not-read-tix-label-err","errorCode":null,"errorMessage":"could not read tix {label}: {err}","messagePattern":"could not read tix (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/history.rs","lineNumber":1488,"sourceCode":"}\n\npub(crate) fn review_number(name: &BStr) -> Option<&BStr> {\n    let suffix = name.strip_prefix(REVIEW_PREFIX)?;\n    (suffix.first().is_some_and(|digit| matches!(digit, b'1'..=b'9')) && suffix.iter().all(u8::is_ascii_digit))\n        .then_some(suffix.as_bstr())\n}\n\nfn refs_with_commit_targets(repo: &gix::Repository, prefix: &[u8], label: &str) -> Result<Vec<Pin>> {\n    let mut out = Vec::new();\n    let references = repo.references().context(\"could not open references\")?;\n    for reference in references\n        .prefixed(prefix.as_bstr())\n        .with_context(|| format!(\"could not iterate tix {label}s\"))?\n    {\n        let mut reference = match reference {\n            Ok(reference) => reference,\n            Err(err) if is_missing_ref(&*err) => continue,\n            Err(err) => return Err(anyhow::anyhow!(\"could not read tix {label}: {err}\")),\n        };\n        let suffix = reference.name().as_bstr().strip_prefix(prefix).unwrap_or_default();\n        let valid_suffix = if prefix == REVIEW_PREFIX {\n            review_number(reference.name().as_bstr()).is_some()\n        } else {\n            suffix.len() >= 4 && suffix.iter().all(u8::is_ascii_alphanumeric)\n        };\n        if !valid_suffix {\n            tracing::warn!(name = %reference.name(), %label, \"ignoring malformed tix reference\");\n            continue;\n        }\n        let name = reference.name().to_owned();\n        let target = reference.target().into_owned();\n        if let Some(target_name) = target.try_name()\n            && crate::edit::undo::ref_chain_reaches_queue(repo, target_name)?\n        {\n            tracing::warn!(name = %name, %label, \"ignoring tix reference into the undo queue\");\n            continue;","sourceCodeStart":1470,"sourceCodeEnd":1506,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/history.rs#L1470-L1506","documentation":"Tix stores its own state (e.g. review and pin entries) under prefixed refs. When enumerating these tix refs, a failure to read a specific reference that is not a benign missing-ref condition is wrapped as `could not read tix {label}: {err}`, where `label` identifies the ref family (e.g. review, pin).","triggerScenarios":"Calling the tix-ref enumeration API (prefixed refs iteration, history.rs:1488) when a ref under the tix prefix (REVIEW_PREFIX or similar) fails to load with an error other than missing-ref — corrupt loose ref file, permission denied, or packed-refs damage under `refs/tix/...`.","commonSituations":"Manual deletion or editing of refs under `refs/tix/`, leftover lock files from a crashed tix run, filesystem permission changes, or interrupted writes to tix state refs.","solutions":["Inspect and repair refs under the tix prefix (e.g. `refs/tix/...`) — remove corrupt loose ref files or stale `.lock` files","Run `git fsck` to confirm ref integrity","Fix filesystem permissions on the tix ref paths","Delete the broken tix state ref and recreate it via the corresponding tix command (e.g. re-create the review)"],"exampleFix":"// recovery (shell) — remove a stale lock blocking a tix ref\nrm .git/refs/tix/review/0001.lock\n# or repair a corrupt loose ref by rewriting the object id\necho <valid-object-id> > .git/refs/tix/review/0001","handlingStrategy":"try-catch","validationCode":"// verify tix state refs exist and are readable before loading\nfor prefix in [\"refs/tix/review/\", \"refs/tix/pin/\"] {\n    let out = std::process::Command::new(\"git\")\n        .args([\"for-each-ref\", prefix, \"--format=%(refname)\"])\n        .output()\n        .expect(\"run git\");\n    if !out.status.success() {\n        eprintln!(\"tix refs under {prefix} unreadable\");\n    }\n}","typeGuard":"fn is_benign_tix_ref_error(err: &dyn std::error::Error) -> bool {\n    err.to_string().to_lowercase().contains(\"not found\")\n}","tryCatchPattern":"match load_tix_refs(&repo, \"review\") {\n    Ok(refs) => refs,\n    Err(e) if e.to_string().starts_with(\"could not read tix\") => {\n        eprintln!(\"tix state ref corrupt: {e}; rebuilding state\");\n        rebuild_tix_state(&repo)?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never edit refs under `refs/tix/` by hand","Clear leftover `.lock` files after a tix crash","Back up tix state refs before bulk ref operations","Run tix commands from a filesystem with stable permissions"],"tags":["git","refs","tix","state"],"backgroundTag":"git-command-failed","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"}