Another fun Emacs bug: dap-mode

Failed to load breakpoints for the current workspace with error: (error "Hash table data is not a list of even length") [209 times]

Emacs debugger frames

Debugger entered--Lisp error: (error "Hash table data is not a list of even length")
  read-from-string("#s(hash-table size 65 test equal rehash-size 1.5 r...")
  dap--read-from-file("/home/jake/.local/doom/etc/.dap-b...")
  dap--after-initialize()
  dap-mode(1)
  dap-auto-configure-mode(1)
  lsp-configure-buffer()
  #f(compiled-function (buf) #<bytecode 0x232e511>)(#<buffer options.go>)
  mapc(#f(compiled-function (buf) #<bytecode 0x232e511>) (#<buffer options.go> #<buffer options_test.go>))
  lsp--on-request(#s(lsp--workspace :ewoc nil :server-capabilities #<hash-table equal 21/21 0xabb17bd> :registered-server-capabilities (#s(lsp--registered-capability :id "workspace/didChangeWatchedFiles-630" :method "workspace/didChangeWatchedFiles" :options #<hash-table equal 1/1 0x1bc7c05>) #s(lsp--registered-capability :id "workspace/didChangeWatchedFiles-629" :method "workspace/didChangeWatchedFiles" :options #<hash-table equal 1/1 0xa76b4dd>)) :root "/home/jake/w/ft/src/FT" :client #s(lsp--client :language-id "go" :add-on? nil :new-connection (:connect #f(compiled-function (filter sentinel name environment-fn) #<bytecode 0x11cb031>) :test\? #f(compiled-function () #<bytecode 0x11caecd>)) :ignore-regexps nil :ignore-messages nil :notification-handlers #<hash-table equal 0/65 0x3a85529> :request-handlers #<hash-table equal 0/65 0x3a854a1> :response-handlers #<hash-table eql 0/65 0x3a853c1> :prefix-function nil :uri-handlers #<hash-table equal 0/65 0x3a85339> :action-handlers #<hash-table equal 0/65 0x3a852b1> :major-modes (go-mode go-dot-mod-mode) :activation-fn nil :priority 0 :server-id gopls :multi-root nil :initialization-options nil :custom-capabilities nil :library-folders-fn lsp-go--library-default-directories :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? t :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn #f(compiled-function () #<bytecode 0x11c3aa1>) :async-request-handlers #<hash-table equal 0/65 0x3a85229> :download-server-fn nil :download-in-progress? nil :buffers nil) :host-root nil :proc #<process gopls> :cmd-proc #<process gopls> :buffers (#<buffer options.go> #<buffer options_test.go>) :semantic-tokens-faces nil :semantic-tokens-modifier-faces nil :extra-client-capabilities nil :status initialized :metadata #<hash-table equal 0/65 0x4a26ef9> :watches #<hash-table equal 0/65 0x4a27021> :workspace-folders nil :last-id 0 :status-string nil :shutdown-action nil :diagnostics #<hash-table equal 4/65 0x4a27425> :work-done-tokens #<hash-table equal 0/65 0x4a277c5>) #<hash-table equal 4/4 0x266334d>)
  lsp--parser-on-message(#<hash-table equal 4/4 0x266334d> #s(lsp--workspace :ewoc nil :server-capabilities #<hash-table equal 21/21 0xabb17bd> :registered-server-capabilities (#s(lsp--registered-capability :id "workspace/didChangeWatchedFiles-630" :method "workspace/didChangeWatchedFiles" :options #<hash-table equal 1/1 0x1bc7c05>) #s(lsp--registered-capability :id "workspace/didChangeWatchedFiles-629" :method "workspace/didChangeWatchedFiles" :options #<hash-table equal 1/1 0xa76b4dd>)) :root "/home/jake/w/ft/src/FT" :client #s(lsp--client :language-id "go" :add-on? nil :new-connection (:connect #f(compiled-function (filter sentinel name environment-fn) #<bytecode 0x11cb031>) :test\? #f(compiled-function () #<bytecode 0x11caecd>)) :ignore-regexps nil :ignore-messages nil :notification-handlers #<hash-table equal 0/65 0x3a85529> :request-handlers #<hash-table equal 0/65 0x3a854a1> :response-handlers #<hash-table eql 0/65 0x3a853c1> :prefix-function nil :uri-handlers #<hash-table equal 0/65 0x3a85339> :action-handlers #<hash-table equal 0/65 0x3a852b1> :major-modes (go-mode go-dot-mod-mode) :activation-fn nil :priority 0 :server-id gopls :multi-root nil :initialization-options nil :custom-capabilities nil :library-folders-fn lsp-go--library-default-directories :before-file-open-fn nil :initialized-fn nil :remote? nil :completion-in-comments? t :path->uri-fn nil :uri->path-fn nil :environment-fn nil :after-open-fn #f(compiled-function () #<bytecode 0x11c3aa1>) :async-request-handlers #<hash-table equal 0/65 0x3a85229> :download-server-fn nil :download-in-progress? nil :buffers nil) :host-root nil :proc #<process gopls> :cmd-proc #<process gopls> :buffers (#<buffer options.go> #<buffer options_test.go>) :semantic-tokens-faces nil :semantic-tokens-modifier-faces nil :extra-client-capabilities nil :status initialized :metadata #<hash-table equal 0/65 0x4a26ef9> :watches #<hash-table equal 0/65 0x4a27021> :workspace-folders nil :last-id 0 :status-string nil :shutdown-action nil :diagnostics #<hash-table equal 4/65 0x4a27425> :work-done-tokens #<hash-table equal 0/65 0x4a277c5>))
  #f(compiled-function (proc input) #<bytecode 0x4a27041>)(#<process gopls> "Content-Length: 160641\15\n\15\n{\"jsonrpc\":\"2.0\",\"method...")

That's a lot of times. The upstream issue seems to suggest that this is caused by an signal interruption where the file became corrupt.

Okay, but I don't even use dap-mode even though the package is installed and configured in doom-emacs. My guess is that at some point I hit C-z (or something else) and Emacs didn't get to finish writing to this file (regardless of whether or not there was user data in there). When it loads the file – to then read it into a hash table – the data is found to be invalid or unusable. I'm not sure which.

However, the thing errored 209 times in a very tight loop.

Needless to say, Emacs wasn't happy. I made it happy by deleting the file that it was trying to load:

→ rm ~/.local/doom/etc/.dap-breakpoints