DEBUG breaks doom
I've been working with Claude code lately and I recently spent $6 in API costs to fix my doom emacs setup. If I leave this blog post here, some other AI training will pick it up to the benefit of some other emacs user.

It all started by trying to run doom upgrade and I got this response
~ ❯ doom doctor
Loading /home/oldbones/.config/emacs/lisp/doom.el (source)...
* 0.014400:*:startup:cli:load: ~/.config/emacs/lisp/lib/debug nil
Package cl is deprecatedMy initial thought was this is a problem with omarchy. Now that I've discovered Claude I decided to let it tackle the problem. It does an amazing job for my productivity, far beyond Aider which I was using before. I wanted to see how it handled a non-software related problem.
Claude started reading source code for doom and bisecting the commits looking for my problem. I would have just nuked it and started over. It was interesting to watch it work
The following is a summary of what I had Claude do. I try my best not to let AI write my blog posts, but not posting this will only benefit Anthropic.
Everything below is written exclusively by Claude
summarize everything we did so that I can either put it in a blog post or add it to a forum
● Doom Emacs: Debugging a Multi-Layer Startup Failure
The Symptoms
- doom run --debug-init produced a Lisp error: void-function set-indent-vars!
- All doom CLI commands (doom help, doom sync, etc.) hung silently after printing two log lines and never returned
Root Cause 1: $DEBUG in the environment
The doom bin script (~/.config/emacs/bin/doom) contains this line:
emacs="$EMACS ${DEBUG:+--debug-init} -q --no-site-file --batch"
Any non-empty $DEBUG variable — including DEBUG=True set for unrelated tools — causes every doom CLI invocation to pass --debug-init to Emacs. This enables debug-on-error=t, which activates the interactive Emacs Lisp debugger. In --batch mode, the debugger blocks
waiting for input that never comes, causing the silent hang.
Fix: Always invoke doom with DEBUG unset: env -u DEBUG doom sync, or unset it in your shell for doom use.
Root Cause 2: Stale loaddefs after a Doom update
Doom Emacs had been updated via git pull, but doom sync had never been run. A new function set-indent-vars! was introduced in lisp/lib/indent.el (commit c0662f6e) but wasn't yet in the generated autoloads file (~/.config/emacs/.local/etc/@/init.30.2.el). When
Emacs loaded the evil module's config, it called this undefined function and crashed.
The loaddefs file itself contains a version guard at line 1:
(or (equal doom-version "3.0.0-pre") (error "Run 'doom sync' to fix this."))
With --debug-init active (due to $DEBUG), this error — and any other load error — hit the interactive debugger instead of being printed and continuing, making the hang invisible.
Fix: env -u DEBUG doom sync
Root Cause 3: Org 9.8 regression in ob-tangle.el
When doom sync finally ran, it attempted to tangle the literate config.org. This failed with:
wrong-type-argument (stringp nil)
org-src-coderef-regexp(nil)
org-babel-tangle-single-block(1)
The bug: Org 9.8's ob-tangle.el calls org-src-coderef-regexp with the raw (nth 6 info) value, which is nil for any src block that doesn't explicitly set a coderef label format. The function requires a string. Org 9.7 (bundled with Emacs 30.2) doesn't exhibit this
— direct tangling works fine. The regression was introduced in commit b523ad491 which changed from (or (extract-from-extra) org-coderef-label-format) (always a string) to (nth 6 info) (can be nil).
The nil was triggered by two structural problems in config.org:
Problem A — #+begin_src with no language:
- theme
#+begin_src ← no language!
(use-package! omarchy-themer ...)
#+end_src ← also had leading whitespace
Fix: #+begin_src emacs-lisp :tangle ~/.config/doom/config.el
Problem B — Unclosed #+begin_src block:
the rest
...
#+begin_src emacs-lisp :tangle ~/.config/doom/config.el :results none
(use-package company-box ...)
(setq-default tab-width 2)← missing #+end_src here!
- org-mode ← heading inside unclosed block confuses parser
When the org-element parser hit a heading inside an unclosed block, org-element-context returned nil for that position, making org-babel-get-src-block-info return nil, and (nth 6 nil) = nil crashed org 9.8's tangle.
Fix: Added the missing #+end_src before * org-mode.
Key Takeaways
- $DEBUG affects doom — it's not just for your app. The doom bin script treats any non-empty value as a request for --debug-init.
- After doom upgrade or git pull on the doom repo, always run doom sync — the loaddefs get stale and functions introduced in new commits won't be available.
- Org 9.8 is stricter about malformed src blocks — unclosed #+begin_src blocks and blocks without a language that worked silently in 9.7 will now crash the tangle. Keep your org files well-formed.
- The debugging approach: doom run --debug-init (with $DEBUG unset!) gives a full Elisp backtrace that immediately points to the broken module and function.
✻ Churned for 32s · 1 background task still running (↓ to manage)