[v2] Error running org-roam-dailies-find-today

I receive an error whenever I call org-roam-dailies-find-today and friends.

save-excursion: Wrong type argument: integer-or-marker-p, nil

Fresh install of Doom. Details:

  • Emacs: GNU Emacs 27.2 (build 1, arm-apple-darwin20.3.0, Carbon Version 164 AppKit 2022.3)
    of 2021-03-28
  • Framework: Doom
  • Org: Org mode version 9.5 (nil @ /Users/jbaty/.emacs.d/.local/straight/build-27.2/org-mode/)
  • Org-roam: 2.0.0

I’m afraid I’m not sure where to look, so I’m posting the debug output below hoping maybe someone can point me in the right direction.

My org-roam directory is ~/org/roam and I’ve left the org-roam-dailies-directory as the default (daily/).

If this should be an issue in Github instead, let me know.

Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil)
  goto-char(nil)
  (save-excursion (goto-char p) (run-hooks 'org-roam-capture-new-node-hook) (org-id-get-create))
  (let (p) (let* ((val (or (org-roam-capture--get :if-new) (user-error "Template needs to specify `:if-new'")))) (if (consp val) (let* ((x9 (car val))) (cond ((eq x9 'file) (let* (...) (if ... ... nil))) ((eq x9 'file+olp) (let* (...) (if ... ... nil))) ((eq x9 'file+head) (let* (...) (if ... ... nil))) ((eq x9 'file+head+olp) (let* (...) (if ... ... nil))) ((eq x9 'node) (let* (...) (if ... ... nil))) (t nil))) nil)) (save-excursion (goto-char p) (run-hooks 'org-roam-capture-new-node-hook) (org-id-get-create)))
  org-roam-capture--goto-location()
  (cond ((plist-get org-roam-capture--info :ref) (let* ((node (and t (org-roam-capture--get-node-from-ref (plist-get org-roam-capture--info :ref))))) (if node (progn (set-buffer (org-capture-target-buffer (org-roam-node-file node))) (goto-char (org-roam-node-point node)) (widen) (org-end-of-subtree t t)) (org-roam-capture--goto-location)))) ((and (org-roam-node-file org-roam-capture--node) (org-roam-node-point org-roam-capture--node)) (set-buffer (org-capture-target-buffer (org-roam-node-file org-roam-capture--node))) (goto-char (org-roam-node-point org-roam-capture--node)) (widen) (org-end-of-subtree t t) (org-roam-node-id org-roam-capture--node)) (t (org-roam-capture--goto-location)))
  (let ((id (cond ((plist-get org-roam-capture--info :ref) (let* ((node ...)) (if node (progn ... ... ... ...) (org-roam-capture--goto-location)))) ((and (org-roam-node-file org-roam-capture--node) (org-roam-node-point org-roam-capture--node)) (set-buffer (org-capture-target-buffer (org-roam-node-file org-roam-capture--node))) (goto-char (org-roam-node-point org-roam-capture--node)) (widen) (org-end-of-subtree t t) (org-roam-node-id org-roam-capture--node)) (t (org-roam-capture--goto-location))))) (org-capture-put :template (org-roam-capture--fill-template (org-capture-get :template))) (org-roam-capture--put :id id) (org-roam-capture--put :finalize (or (org-capture-get :finalize) (org-roam-capture--get :finalize))))
  org-roam-capture--get-point()
  org-capture-set-target-location()
  org-capture-goto-target("d")
  #f(compiled-function (&optional goto keys) "Capture something.\n\\<org-capture-mode-map>\nThis will let you select a template from `org-capture-templates', and\nthen file the newly captured information.  The text is immediately\ninserted at the target location, and an indirect buffer is shown where\nyou can edit it.  Pressing `\\[org-capture-finalize]' brings you back to the previous\nstate of Emacs, so that you can continue your work.\n\nWhen called interactively with a `\\[universal-argument]' prefix argument GOTO, don't\ncapture anything, just go to the file/headline where the selected\ntemplate stores its notes.\n\nWith a `\\[universal-argument] \\[universal-argument]' prefix argument, go to the last note stored.\n\nWhen called with a `C-0' (zero) prefix, insert a template at point.\n\nWhen called with a `C-1' (one) prefix, force prompting for a date when\na datetree entry is made.\n\nELisp programs can set KEYS to a string associated with a template\nin `org-capture-templates'.  In this case, interactive selection\nwill be bypassed.\n\nIf `org-capture-use-agenda-date' is non-nil, capturing from the\nagenda will use the date at point as the default date.  Then, a\n`C-1' prefix will tell the capture process to use the HH:MM time\nof the day at point (if any) or the current HH:MM time." (interactive "P") #<bytecode 0x4391a41b>)((4) "d")
  apply(#f(compiled-function (&optional goto keys) "Capture something.\n\\<org-capture-mode-map>\nThis will let you select a template from `org-capture-templates', and\nthen file the newly captured information.  The text is immediately\ninserted at the target location, and an indirect buffer is shown where\nyou can edit it.  Pressing `\\[org-capture-finalize]' brings you back to the previous\nstate of Emacs, so that you can continue your work.\n\nWhen called interactively with a `\\[universal-argument]' prefix argument GOTO, don't\ncapture anything, just go to the file/headline where the selected\ntemplate stores its notes.\n\nWith a `\\[universal-argument] \\[universal-argument]' prefix argument, go to the last note stored.\n\nWhen called with a `C-0' (zero) prefix, insert a template at point.\n\nWhen called with a `C-1' (one) prefix, force prompting for a date when\na datetree entry is made.\n\nELisp programs can set KEYS to a string associated with a template\nin `org-capture-templates'.  In this case, interactive selection\nwill be bypassed.\n\nIf `org-capture-use-agenda-date' is non-nil, capturing from the\nagenda will use the date at point as the default date.  Then, a\n`C-1' prefix will tell the capture process to use the HH:MM time\nof the day at point (if any) or the current HH:MM time." (interactive "P") #<bytecode 0x4391a41b>) ((4) "d"))
  (let ((+file-templates-inhibit t)) (apply orig-fn args))
  +file-templates-inhibit-in-org-capture-a(#f(compiled-function (&optional goto keys) "Capture something.\n\\<org-capture-mode-map>\nThis will let you select a template from `org-capture-templates', and\nthen file the newly captured information.  The text is immediately\ninserted at the target location, and an indirect buffer is shown where\nyou can edit it.  Pressing `\\[org-capture-finalize]' brings you back to the previous\nstate of Emacs, so that you can continue your work.\n\nWhen called interactively with a `\\[universal-argument]' prefix argument GOTO, don't\ncapture anything, just go to the file/headline where the selected\ntemplate stores its notes.\n\nWith a `\\[universal-argument] \\[universal-argument]' prefix argument, go to the last note stored.\n\nWhen called with a `C-0' (zero) prefix, insert a template at point.\n\nWhen called with a `C-1' (one) prefix, force prompting for a date when\na datetree entry is made.\n\nELisp programs can set KEYS to a string associated with a template\nin `org-capture-templates'.  In this case, interactive selection\nwill be bypassed.\n\nIf `org-capture-use-agenda-date' is non-nil, capturing from the\nagenda will use the date at point as the default date.  Then, a\n`C-1' prefix will tell the capture process to use the HH:MM time\nof the day at point (if any) or the current HH:MM time." (interactive "P") #<bytecode 0x4391a41b>) (4) "d")
  apply(+file-templates-inhibit-in-org-capture-a #f(compiled-function (&optional goto keys) "Capture something.\n\\<org-capture-mode-map>\nThis will let you select a template from `org-capture-templates', and\nthen file the newly captured information.  The text is immediately\ninserted at the target location, and an indirect buffer is shown where\nyou can edit it.  Pressing `\\[org-capture-finalize]' brings you back to the previous\nstate of Emacs, so that you can continue your work.\n\nWhen called interactively with a `\\[universal-argument]' prefix argument GOTO, don't\ncapture anything, just go to the file/headline where the selected\ntemplate stores its notes.\n\nWith a `\\[universal-argument] \\[universal-argument]' prefix argument, go to the last note stored.\n\nWhen called with a `C-0' (zero) prefix, insert a template at point.\n\nWhen called with a `C-1' (one) prefix, force prompting for a date when\na datetree entry is made.\n\nELisp programs can set KEYS to a string associated with a template\nin `org-capture-templates'.  In this case, interactive selection\nwill be bypassed.\n\nIf `org-capture-use-agenda-date' is non-nil, capturing from the\nagenda will use the date at point as the default date.  Then, a\n`C-1' prefix will tell the capture process to use the HH:MM time\nof the day at point (if any) or the current HH:MM time." (interactive "P") #<bytecode 0x4391a41b>) ((4) "d"))
  org-capture((4) "d")
  (let* ((props (plist-put props :call-location (point-marker))) (org-capture-templates (mapcar #'(lambda (template) (org-roam-capture--convert-template template props)) (or templates org-roam-capture-templates))) (org-roam-capture--node node) (org-roam-capture--info info)) (if (and (not keys) (= (length org-capture-templates) 1)) (progn (setq keys (car (car org-capture-templates))))) (org-capture goto keys))
  (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '(:goto :keys :node :info :props :templates :allow-other-keys)) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) ((car (cdr (memq ... --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:goto :keys :node ..." (car --cl-keys--)))))) (let* ((props (plist-put props :call-location (point-marker))) (org-capture-templates (mapcar #'(lambda (template) (org-roam-capture--convert-template template props)) (or templates org-roam-capture-templates))) (org-roam-capture--node node) (org-roam-capture--info info)) (if (and (not keys) (= (length org-capture-templates) 1)) (progn (setq keys (car (car org-capture-templates))))) (org-capture goto keys)))
  (let* ((goto (car (cdr (plist-member --cl-rest-- ':goto)))) (keys (car (cdr (plist-member --cl-rest-- ':keys)))) (node (car (cdr (plist-member --cl-rest-- ':node)))) (info (car (cdr (plist-member --cl-rest-- ':info)))) (props (car (cdr (plist-member --cl-rest-- ':props)))) (templates (car (cdr (plist-member --cl-rest-- ':templates))))) (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '...) (setq --cl-keys-- (cdr ...))) ((car (cdr ...)) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:goto :keys :node ..." (car --cl-keys--)))))) (let* ((props (plist-put props :call-location (point-marker))) (org-capture-templates (mapcar #'(lambda ... ...) (or templates org-roam-capture-templates))) (org-roam-capture--node node) (org-roam-capture--info info)) (if (and (not keys) (= (length org-capture-templates) 1)) (progn (setq keys (car (car org-capture-templates))))) (org-capture goto keys))))
  org-roam-capture-(:goto (4) :node #s(org-roam-node :id nil :file nil :level nil :point nil :todo nil :priority nil :scheduled nil :deadline nil :title nil :tags nil :aliases nil :refs nil) :templates (("d" "default" entry "* %?" :if-new `(file+head ,(concat org-roam-dailies-directory "%<%Y-%m-%d>.org") "#+title: %<%Y-%m-%d>\n"))) :props (:default-time (24709 25874 545082 0) :call-location #<marker at 636 in 20210422092410-home_assistant.org>))
  org-roam-dailies--capture((24709 25874 545082 0) t)
  org-roam-dailies-capture-today(t)
  org-roam-dailies-find-today()
  funcall-interactively(org-roam-dailies-find-today)
  call-interactively(org-roam-dailies-find-today nil nil)
  command-execute(org-roam-dailies-find-today)

As far as I can see in the logs:
user-error "Template needs to specify :if-new'"

Looks like your template config has that property missing

Can’t be sure but two possible starting points from top parts of the error.

  1. Your capture template (:if-new missing?)
  2. Org-ID can be used as navigation

I’m assuming dailies is supported in V2 (I don’t know because i don’t use it).

I hadn’t considered that dailies might not be supported (yet).

As for the template :if-new bit, I do not have my own org-roam-capture-template configured so it’s using the default, which is:

(("d" "default" plain "%?" :if-new
  (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
  :unnarrowed t))

I don’t spot anything wrong there. :if-new is there, so that makes the error even more confusing to me :). Thanks for looking at it.

@jbaty

Change the dailies-capture-templates like this below, and it works on my end.

I think the default one has a syntactic issue (it does not return correct values that the calling function expects).

In this example, instead of relying on org-roam-dailies-directories user option, I am typing the subfolder for dailes directly (daily/); the rest should be identical to the default.

(setq org-roam-dailies-capture-templates
      '(("d" "default" entry "* %?" :if-new
         (file+head "daily/%<%Y-%m-%d>.org"
                    "#+title: %<%Y-%m-%d>"))))

This version below has worked – it uses different way to use org-roam-dailies-directory user option… Not sure why the original default does not work, though.

(setq org-roam-dailies-capture-templates
      '(("d" "default" entry "* %?" :if-new
         (file+head "%(concat org-roam-dailies-directory \"/%<%Y-%m-%d>.org\")"
                    "#+title: %<%Y-%m-%d>"))))

@jbaty
Perhaps it is worth logging an issue on GH – since I don’t use dailies, I am not really keen… Sorry.

Boom! This is great, thanks for debugging it for me. I really should get better at all this.

I’ll open an issue in GH. Thanks again for your help!

1 Like