{"record":{"id":"5d1848e79c4ed9b5","repo":"d2lang/d2","slug":"s-is-invalid","errorCode":null,"errorMessage":"\"%s\" is invalid","messagePattern":"\"(.+?)\" is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"d2lsp/d2lsp.go","lineNumber":25,"sourceCode":"\n\t\"github.com/d2lang/d2/d2ast\"\n\t\"github.com/d2lang/d2/d2ir\"\n\t\"github.com/d2lang/d2/d2parser\"\n\t\"github.com/d2lang/d2/lib/memfs\"\n)\n\nfunc GetRefRanges(path string, fs map[string]string, boardPath []string, key string) (ranges []d2ast.Range, importRanges []d2ast.Range, _ error) {\n\tm, err := getBoardMap(path, fs, boardPath)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tmk, err := d2parser.ParseMapKey(key)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif mk.Key == nil && len(mk.Edges) == 0 {\n\t\treturn nil, nil, fmt.Errorf(`\"%s\" is invalid`, key)\n\t}\n\n\tvar f *d2ir.Field\n\tif mk.Key != nil {\n\t\tfor _, p := range mk.Key.Path {\n\t\t\tf = m.GetField(p.Unbox())\n\t\t\tif f == nil {\n\t\t\t\treturn nil, nil, nil\n\t\t\t}\n\t\t\tm = f.Map()\n\t\t}\n\t}\n\n\tif len(mk.Edges) > 0 {\n\t\teids := d2ir.NewEdgeIDs(mk)\n\t\tvar edges []*d2ir.Edge\n\t\tfor _, eid := range eids {\n\t\t\tedges = append(edges, m.GetEdges(eid, nil, nil)...)","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/d2lsp/d2lsp.go#L7-L43","documentation":"GetRefRanges parses the given key string into a MapKey AST node; if the parse succeeds but yields neither a Key nor Edges, the string is not a valid D2 key expression, so it cannot have reference ranges and this error is returned.","triggerScenarios":"Calling d2lsp.GetRefRanges(key, ...) with an empty string, whitespace, or a token sequence that parses to an empty MapKey (no key path and no edge).","commonSituations":"LSP/tooling callers passing raw user selections that include only comments or operators; slicing document text incorrectly so the key text is empty; feeding malformed fragments from external tools.","solutions":["Trim and validate the key string is a non-empty valid D2 key (e.g. \"a.b\" or \"a -> b\") before calling GetRefRanges","Check that the text extraction (position slicing) around the cursor captures the key, not just whitespace","Parse the document with d2parser first and pass a key from a real MapKey node"],"exampleFix":"// before\nranges, _, err := d2lsp.GetRefRanges(\"   \", fs, boardPath, m)\n// after\nkey := strings.TrimSpace(selection)\nif key == \"\" { return nil, nil, errors.New(\"empty key\") }\nranges, _, err := d2lsp.GetRefRanges(key, fs, boardPath, m)","handlingStrategy":"validation","validationCode":"key = strings.TrimSpace(key)\nif key == \"\" { return errors.New(\"key must be a non-empty D2 key\") }\nif mk, err := d2parser.ParseMapKey(key); err != nil || (mk.Key == nil && len(mk.Edges) == 0) {\n\treturn fmt.Errorf(\"invalid key %q\", key)\n}","typeGuard":"func isValidD2Key(key string) bool {\n\tmk, err := d2parser.ParseMapKey(key)\n\treturn err == nil && (mk.Key != nil || len(mk.Edges) > 0)\n}","tryCatchPattern":"ranges, _, err := d2lsp.GetRefRanges(key, fs, boardPath, m)\nif err != nil && strings.Contains(err.Error(), \"is invalid\") {\n\treturn fmt.Errorf(\"skipping non-key selection %q\", key)\n}","preventionTips":["Trim whitespace/comments from user selections before treating them as keys","Parse documents with d2parser and reuse real MapKey nodes","Unit-test key extraction around cursor positions"],"tags":["d2","lsp","parsing","invalid-input"],"backgroundTag":"invalid-d2-key","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}