{"record":{"id":"252d66fda7666593","repo":"ethereum/go-ethereum","slug":"error-decoding-contract-deployer-hex-s-v","errorCode":null,"errorMessage":"error decoding contract deployer hex %s:\n%v","messagePattern":"error decoding contract deployer hex (.+?):\n(.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"accounts/abi/bind/v2/dep_tree.go","lineNumber":117,"sourceCode":"\t// Don't re-deploy aliased or previously-deployed contracts\n\tif addr, ok := d.deployedAddrs[metadata.ID]; ok {\n\t\treturn addr, nil\n\t}\n\t// If this contract/library depends on other libraries deploy them\n\t// (and their dependencies) first\n\tdeployerCode := metadata.Bin\n\tfor _, dep := range metadata.Deps {\n\t\taddr, err := d.linkAndDeploy(dep)\n\t\tif err != nil {\n\t\t\treturn common.Address{}, err\n\t\t}\n\t\t// Link their deployed addresses into the bytecode to produce\n\t\tdeployerCode = strings.ReplaceAll(deployerCode, \"__$\"+dep.ID+\"$__\", strings.ToLower(addr.String()[2:]))\n\t}\n\t// Finally, deploy the top-level contract.\n\tcode, err := hex.DecodeString(deployerCode[2:])\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"error decoding contract deployer hex %s:\\n%v\", deployerCode[2:], err))\n\t}\n\taddr, tx, err := d.deployFn(d.inputs[metadata.ID], code)\n\tif err != nil {\n\t\treturn common.Address{}, err\n\t}\n\td.deployedAddrs[metadata.ID] = addr\n\td.deployerTxs[metadata.ID] = tx\n\treturn addr, nil\n}\n\n// result returns a DeploymentResult instance referencing contracts deployed\n// and not including any overrides specified for this deployment.\nfunc (d *depTreeDeployer) result() *DeploymentResult {\n\t// filter the override addresses from the deployed address set.\n\tfor pattern := range d.deployedAddrs {\n\t\tif _, ok := d.deployerTxs[pattern]; !ok {\n\t\t\tdelete(d.deployedAddrs, pattern)\n\t\t}","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/ethereum/go-ethereum/blob/6bb0588ad8e7f922e4ad5580f51265a4097af08f/accounts/abi/bind/v2/dep_tree.go#L99-L135","documentation":"The v2 deployment tree links dependency addresses into the deployer bytecode (replacing __$<id>__$ placeholders) and then hex-decodes the final deployerCode with hex.DecodeString after stripping the 0x prefix. If the resulting string contains non-hex characters or odd length, decoding fails and the code panics with the offending hex and the decode error — this indicates corrupted or badly generated deployment metadata, not a runtime chain condition.","triggerScenarios":"deployFn path where metadata.Bin contains invalid hex after dependency substitution: an unresolved/misspelled placeholder, a bin artifact that was truncated or contains 'undefined' from a JS build step, or manual editing of the linked bytecode string.","commonSituations":"Feeding bind v2 DeploymentMetadata assembled by hand or by a buggy codegen step; solc output post-processing that mangles the bin (link placeholders replaced with address strings including '0x' or empty values); partial file writes leaving truncated hex.","solutions":["Regenerate the deployment metadata/binaries from a clean build (solc + abigen/bind tooling) instead of patching hex by hand.","Verify every __$id$__ placeholder in metadata.Bin has a matching dependency in metadata.Deps so substitution leaves pure hex.","Sanity-check the string before deploy: even length and only [0-9a-fA-F] after stripping 0x.","Inspect the panic text: it prints the exact bad hex, showing where corruption begins."],"exampleFix":"// before\nmeta.Bin = strings.Replace(meta.Bin, \"__$lib__$__\", \"0x9a0f...\", 1) // embeds 0x -> invalid hex\n\n// after\nmeta.Bin = strings.Replace(meta.Bin, \"__$lib__$__\", \"9a0f...\", 1) // bare hex, no 0x","handlingStrategy":"validation","validationCode":"func validHexCode(code string) bool {\n\tc := strings.TrimPrefix(code, \"0x\")\n\tif len(c)%2 != 0 {\n\t\treturn false\n\t}\n\tfor _, r := range c {\n\t\tif !strings.ContainsRune(\"0123456789abcdefABCDEF\", r) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n// guard: if !validHexCode(strings.ReplaceAll(meta.Bin, placeholder, bareHexAddr)) { return errors.New(\"corrupt deployer bin\") }","typeGuard":"func isLinkedBytecode(bin string) bool {\n\treturn !strings.Contains(bin, \"__$\") && validHexCode(bin)\n}","tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\tif msg, _ := r.(string); strings.HasPrefix(msg, \"error decoding contract deployer hex\") {\n\t\t\treturn common.Address{}, errors.New(\"deployer bytecode is not valid hex; regenerate bind metadata\")\n\t\t}\n\t\tpanic(r)\n\t}\n}()","preventionTips":["Never hand-edit linked bytecode; regenerate with abigen/solc.","Ensure every link placeholder has a dependency entry.","Checksum/validate bin artifacts in CI before deployment runs."],"tags":["go-ethereum","abi-bind","linking","hex","panic"],"backgroundTag":null,"analyzedSha":"6bb0588ad8e7f922e4ad5580f51265a4097af08f","analyzedAt":"2026-08-15T10:06:53.996Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}