{"record":{"id":"de58154473ce0253","repo":"gitbutlerapp/gitbutler","slug":"invalid-at-index-index-e","errorCode":null,"errorMessage":"invalid '{}' at index {index}: {e}","messagePattern":"invalid '(.+?)' at index (.+?): (.+?)","errorType":"validation","errorClass":"napi::Error","httpStatus":null,"severity":"error","filePath":"crates/but-api-macros/src/lib.rs","lineNumber":1577,"sourceCode":"                                    napi::Status::InvalidArg,\n                                    format!(\"invalid '{}': {e}\", stringify!(#param_name)),\n                                )\n                            })\n                        })\n                        .transpose()?;\n                });\n                call_arg_idents.push(quote! { #ident });\n            } else if *last_ident == \"Vec\" && is_hex_hash_container_path(&mapping.json_ty, \"Vec\") {\n                // Vec<ObjectId> via Vec<HexHash> → Vec<String>, then parse each entry\n                params.push(quote! { #param_name: Vec<String> });\n                names.push(param_name.to_string());\n                conversions.push(quote! {\n                    let #ident: Vec<gix::ObjectId> = #param_name\n                        .into_iter()\n                        .enumerate()\n                        .map(|(index, value)| {\n                            ::std::str::FromStr::from_str(&value).map_err(|e: gix::hash::decode::Error| {\n                                napi::Error::new(\n                                    napi::Status::InvalidArg,\n                                    format!(\"invalid '{}' at index {index}: {e}\", stringify!(#param_name)),\n                                )\n                            })\n                        })\n                        .collect::<std::result::Result<Vec<_>, napi::Error>>()?;\n                });\n                let call_ident = match &*pat_ty.ty {\n                    syn::Type::Reference(r) => {\n                        let mutability = &r.mutability;\n                        quote! { &#mutability #ident }\n                    }\n                    _ => quote! { #ident },\n                };\n                call_arg_idents.push(call_ident);\n            } else {\n                // Fallback: use serde_json::Value with ts_arg_type for proper TS typing\n                let ts_type_str = type_to_ts_name(&pat_ty.ty);","sourceCodeStart":1559,"sourceCodeEnd":1595,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-api-macros/src/lib.rs#L1559-L1595","documentation":"This error is generated by the but_api NAPI macro when converting a Vec<String> parameter back into Vec<gix::ObjectId> for a GitButler API call. One of the strings in the array is not a valid Git object ID (40-char SHA-1 or 64-char SHA-256 hex). The inner gix::hash::decode::Error is wrapped into a napi::Error with Status::InvalidArg, naming the parameter and the failing array index.","triggerScenarios":"Calling any generated but_api NAPI function whose parameter maps to Vec<gix::ObjectId> (via maps_vec_object_id_to_vec_string_napi_param_and_parser) with an array containing a string that fails gix::hash::from_str decoding — e.g. wrong length, non-hex characters, or an empty string in the array.","commonSituations":"JS/TS callers pass truncated commit IDs from UI copy/paste, pass branch names instead of object IDs, pass IDs from a different hash algorithm, or include null/undefined coerced to 'null'/'undefined' strings inside the array.","solutions":["Print and inspect the array element at the reported index and fix it to a full valid hex object ID","Verify the object actually exists (git rev-parse <value>) before calling the API","Check that you are not passing branch/ref names where object IDs are required","Ensure consistent hash length (40 vs 64 chars) matching the repository's object format"],"exampleFix":"// before\napi.commitFiles(['abc123', '9f8e7d...']);  // truncated id\n// after\napi.commitFiles(['9f8e7d6c5b4a3210fedcba9876543210abcdef12']);  // full 40-char hex","handlingStrategy":"validation","validationCode":"function isValidObjectId(s) { return typeof s === 'string' && /^[0-9a-f]{40}$|^[0-9a-f]{64}$/.test(s); }\nids.forEach((id, i) => { if (!isValidObjectId(id)) throw new Error(`bad object id at index ${i}: ${id}`); });","typeGuard":"const isObjectId = (v: unknown): v is string => typeof v === 'string' && /^[0-9a-f]{40}([0-9a-f]{24})?$/.test(v);","tryCatchPattern":"try { api.commitFiles(ids); } catch (e) { if (String(e.message).includes('invalid')) { const idx = /index (\\d+)/.exec(e.message); console.error('bad id at', idx?.[1]); } throw e; }","preventionTips":["Always pass full-length hex hashes, never short prefixes","Resolve ref names to object IDs before calling ID-typed APIs","Validate array elements with a hex regex before batch calls"],"tags":["napi","object-id","hex-decode","invalid-argument"],"backgroundTag":"invalid-argument-format","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}