{"record":{"id":"029dc21bda876813","repo":"d2lang/d2","slug":"key-does-not-exist","errorCode":null,"errorMessage":"key does not exist","messagePattern":"key does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2oracle/edit.go","lineNumber":1736,"sourceCode":"\tif len(mk.Edges) > 0 && mk.EdgeKey == nil {\n\t\t// TODO: Not a fan of this dual interpretation depending on mk.Edges.\n\t\t// Maybe we remove Rename and just have Move.\n\t\tmk2, err := d2parser.ParseMapKey(newName)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", err\n\t\t}\n\n\t\tmk2.Key = mk.Key\n\t\tmk = mk2\n\t} else {\n\t\t_, ok := d2ast.ReservedKeywords[newName]\n\t\tif ok {\n\t\t\treturn nil, \"\", fmt.Errorf(\"cannot rename to reserved keyword: %#v\", newName)\n\t\t}\n\t\tif mk.Key != nil {\n\t\t\tobj, ok := boardG.Root.HasChild(d2graph.Key(mk.Key))\n\t\t\tif !ok {\n\t\t\t\treturn nil, \"\", fmt.Errorf(\"key does not exist\")\n\t\t\t}\n\t\t\t// If attempt to name something \"x\", but \"x\" already exists, rename it \"x 2\" instead\n\t\t\tgeneratedName, _, err := generateUniqueKey(boardG, newName, obj, nil)\n\t\t\tif err == nil {\n\t\t\t\tnewName = generatedName\n\t\t\t}\n\t\t}\n\t\t// TODO: Handle mk.EdgeKey\n\t\tmk.Key.Path[len(mk.Key.Path)-1] = d2ast.MakeValueBox(d2ast.RawString(newName, true)).StringBox()\n\t}\n\n\tg, err = move(g, boardPath, key, d2format.Format(mk), false)\n\treturn g, newName, err\n}\n\nfunc trimReservedSuffix(path []*d2ast.StringBox) []*d2ast.StringBox {\n\tfor i, p := range path {\n\t\tif _, ok := d2ast.ReservedKeywords[p.Unbox().ScalarString()]; ok {","sourceCodeStart":1718,"sourceCodeEnd":1754,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2oracle/edit.go#L1718-L1754","documentation":"Rename checks that the key being renamed actually exists as a child of the board's root via HasChild; if not found, it returns \"key does not exist\". The rename is aborted because there is nothing to rename.","triggerScenarios":"d2oracle.Rename(g, boardPath, key, newName) where key (parsed via d2parser) does not match an existing object path on the target board: typo, object already deleted, or key living on a different board than boardPath.","commonSituations":"Stale editor state where the object was removed by a previous operation; renaming an object defined via glob/import not addressable by this literal key; case mismatches in key.","solutions":["Check g.Root.HasChild(d2graph.Key(parsedKey)) or equivalent before renaming.","Correct the key string; remember d2 keys are case-sensitive.","Recompile the graph so it reflects the current object set.","Target the board where the object is actually defined via boardPath."],"exampleFix":"// before\nd2oracle.Rename(g, nil, \"server.old\", \"server.new\") // server.old gone\n// after\nif _, ok := g.Root.HasChild([]string{\"server\",\"old\"}); ok {\n    d2oracle.Rename(g, nil, \"server.old\", \"server.new\")\n}","handlingStrategy":"validation","validationCode":"import (\"oss.terrastruct.com/d2/d2graph\"; \"oss.terrastruct.com/d2/d2parser\")\nmk, _ := d2parser.ParseMapKey(key)\nif _, ok := g.Root.HasChild(d2graph.Key(mk)); !ok {\n    return fmt.Errorf(\"cannot rename: %q does not exist\", key)\n}","typeGuard":"func keyExists(g *d2graph.Graph, key string) bool {\n    mk, err := d2parser.ParseMapKey(key)\n    if err != nil { return false }\n    _, ok := g.Root.HasChild(d2graph.Key(mk))\n    return ok\n}","tryCatchPattern":"ng, _, err := d2oracle.Rename(g, boardPath, key, newName)\nif err != nil && strings.Contains(err.Error(), \"key does not exist\") {\n    return fmt.Errorf(\"object %q no longer exists; refresh diagram\", key)\n}","preventionTips":["Verify the key exists on the target board before renaming.","Remember keys are case-sensitive.","Refresh editor state after any prior delete/rename.","Confirm the object is not glob/import generated before literal renames."],"tags":["d2","rename","key-not-found"],"backgroundTag":"object-not-found","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}