{"record":{"id":"7f0502cd5b9810bd","repo":"jdx/mise","slug":"unsupported-git-object-id-commit","errorCode":null,"errorMessage":"unsupported Git object id: {commit}","messagePattern":"unsupported Git object id: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/history/shadow.rs","lineNumber":1487,"sourceCode":"        let mut args = vec![\"commit-tree\".to_string(), tree.to_string()];\n        for parent in parents {\n            args.push(\"-p\".to_string());\n            args.push(parent.to_string());\n        }\n        args.push(\"-m\".to_string());\n        args.push(message.to_string());\n        self.output_str(PlumbingCall::new(args))\n    }\n\n    /// Moves `name` to `commit` only if it still points at `expected`\n    /// (`None`: must not exist).\n    pub(crate) fn update_ref(\n        &self,\n        name: &str,\n        commit: &str,\n        expected: Option<&str>,\n    ) -> Result<()> {\n        eyre::ensure!(\n            matches!(commit.len(), 40 | 64),\n            \"unsupported Git object id: {commit}\"\n        );\n        let zero = \"0\".repeat(commit.len());\n        self.git.run(PlumbingCall::new([\n            \"update-ref\",\n            name,\n            commit,\n            expected.unwrap_or(&zero),\n        ]))\n    }\n\n    /// Deletes a ref if it exists.\n    pub(crate) fn delete_ref(&self, name: &str) -> Result<()> {\n        if self.ref_oid(name)?.is_some() {\n            self.git\n                .run(PlumbingCall::new([\"update-ref\", \"-d\", name]))?;\n        }","sourceCodeStart":1469,"sourceCodeEnd":1505,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/history/shadow.rs#L1469-L1505","documentation":"`update_ref` in the history shadow repo only accepts Git object ids of SHA-1 (40 hex chars) or SHA-256 (64 hex chars) length before shelling out to `git update-ref`. Any other string — short hash, symbolic ref name, or empty/zero-length mismatch — is rejected with this error to avoid passing malformed ids to git.","triggerScenarios":"Calling `update_ref(name, commit, expected)` with a `commit` string whose length is not 40 or 64 — e.g. a 7-char short hash, a full ref name like `refs/heads/main`, or a corrupted oid from a parsed log.","commonSituations":"Downstream code stored a shortened commit hash from user input or display output; a repo configured for an unexpected hash algorithm produced ids of a different length; a test or script passed a placeholder value.","solutions":["Resolve the short hash or ref to a full object id first (`git rev-parse <ref>`) and pass the full 40/64-char id.","Check the shadow repo's object format (core.repositoryformatversion / hash algorithm) to confirm it matches the id length being passed.","Fix the caller that truncated or substituted the oid before reaching update_ref."],"exampleFix":"// before\nshadow.update_ref(\"refs/mise/history\", &commit[..7], None)?;\n\n// after\nlet full = shadow.git.run(PlumbingCall::new([\"rev-parse\", &commit[..7]]))?.trim().to_string();\nshadow.update_ref(\"refs/mise/history\", &full, None)?;","handlingStrategy":"validation","validationCode":"fn is_full_oid(s: &str) -> bool {\n    (s.len() == 40 || s.len() == 64) && s.chars().all(|c| c.is_ascii_hexdigit())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass full-length object ids to update-ref, never short hashes or ref names.","Resolve refs with `git rev-parse` before updating.","Keep hash-algorithm settings consistent across tooling."],"tags":["git","validation","object-id","argument-format"],"backgroundTag":"invalid-argument-format","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}