{"record":{"id":"985da1392791de56","repo":"canopy-network/canopy","slug":"nickname-already-used","errorCode":null,"errorMessage":"nickname already used","messagePattern":"nickname already used","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/crypto/keystore.go","lineNumber":97,"sourceCode":"func (ks *Keystore) Import(encrypted *EncryptedPrivateKey, opts ImportOpts) error {\n\t// TODO: better naming\n\tencrypted.KeyAddress = hex.EncodeToString(opts.Address)\n\tencrypted.KeyNickname = opts.Nickname\n\n\t// this is needed to prevent saving various nicknames for the same address\n\tvar oldNickname string\n\toldKey := ks.AddressMap[encrypted.KeyAddress]\n\tif oldKey != nil {\n\t\toldNickname = oldKey.KeyNickname\n\t}\n\tif oldNickname != \"\" {\n\t\tdelete(ks.NicknameMap, oldNickname)\n\t}\n\n\tif opts.Nickname != \"\" {\n\t\t_, ok := ks.NicknameMap[opts.Nickname]\n\t\tif ok && opts.Nickname != oldNickname {\n\t\t\treturn errors.New(\"nickname already used\")\n\t\t}\n\t\tks.NicknameMap[opts.Nickname] = encrypted.KeyAddress\n\t}\n\n\tks.AddressMap[encrypted.KeyAddress] = encrypted\n\n\treturn nil\n}\n\ntype ImportRawOpts struct {\n\tNickname string\n}\n\n// ImportRaw() imports a non-encrypted private key to the store, but encrypts it given a password\nfunc (ks *Keystore) ImportRaw(privateKeyBytes []byte, password string, opts ImportRawOpts) (address string, err error) {\n\tif password == \"\" {\n\t\treturn \"\", fmt.Errorf(\"invalid password\")\n\t}","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/canopy-network/canopy/blob/ee8197d91dd410f6592cb650a94c925ee6dc8bad/lib/crypto/keystore.go#L79-L115","documentation":"Keystore.Import returns \"nickname already used\" when importing a key with an ImportOptions.Nickname that is already mapped to a different address in the keystore's NicknameMap. Each nickname must uniquely identify one address to keep lookups unambiguous.","triggerScenarios":"Import/ImportRaw called twice with the same opts.Nickname for two different keys; renaming a key to a nickname owned by another key.","commonSituations":"Re-running an import script that reuses a fixed nickname; exporting/importing across keystores where a nickname already exists; automation that doesn't detect existing nicknames.","solutions":["Pick a unique nickname or generate one (suffix/timestamp) before importing","Omit opts.Nickname to import without a nickname","If re-importing the same key intentionally, clear/replace the old nickname mapping first"],"exampleFix":"// before\n_, err := ks.ImportRaw(pk, &keystore.ImportOptions{Nickname: \"validator\"}) // second import\n// after\nif _, exists := ks.NicknameMap[\"validator\"]; exists {\n\topts.Nickname = \"validator-2\"\n}\n_, err := ks.ImportRaw(pk, opts)","handlingStrategy":"try-catch","validationCode":"if opts.Nickname != \"\" {\n\tif addr, ok := ks.NicknameMap[opts.Nickname]; ok && addr != encrypted.KeyAddress {\n\t\topts.Nickname = opts.Nickname + \"-\" + fmt.Sprintf(\"%d\", time.Now().Unix())\n\t}\n}","typeGuard":null,"tryCatchPattern":"_, err := ks.ImportRaw(pk, opts)\nif err != nil && strings.Contains(err.Error(), \"nickname already used\") {\n\topts.Nickname = uniquify(opts.Nickname)\n\t_, err = ks.ImportRaw(pk, opts)\n}","preventionTips":["Check NicknameMap before importing with a fixed nickname","Make import scripts idempotent (reuse the existing entry if the address matches)","Generate nicknames with unique suffixes in automation"],"tags":["keystore","conflict","import"],"backgroundTag":"file-already-exists","analyzedSha":"ee8197d91dd410f6592cb650a94c925ee6dc8bad","analyzedAt":"2026-09-06T09:30:15.973Z","contentChangedAt":"2026-09-06T09:30:15.973Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}