Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

`*file*` stays bound in a session after an eval with `:file`

Open Beginner friendly
#505 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 3 days

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
clojure, java

Research direction

Read src/clojure/nrepl/middleware/session.clj, especially the add-per-message-bindings and saved session bindings around lines 140 and 208–212. Reproduce the behavior with the provided eval and load-file sequence, then check how *file* behaves in the following eval. Done when evals without :file see "NO_SOURCE_PATH" and definitions no longer inherit the previous file metadata.

Written by the indexing model from the issue text.

Description

Found while working on neorepl: after neorepl load x.clj, neorepl where on a function defined later in the same session with neorepl eval pointed at x.clj.

Expected behavior

An eval without a :file sees *file* as "NO_SOURCE_PATH", whatever the session evaluated before it.

Actual behavior

The session keeps the *file* of its last eval with a :file, so everything defined there afterwards gets that file as its :file metadata, and compile errors are reported at it (Syntax error compiling at (/tmp/x.clj:1:1)). load-file does the same since 1.5, when it became an eval with :file.

add-per-message-bindings binds *file* only when the message has a :file (session.clj#L140-L141), and the bindings the session saves after each message drop only *msg* and Compiler/LOADER (session.clj#L208-L212). Binding *file* for every message, or dropping it there too, fixes it.

Steps to reproduce the problem

(require '[nrepl.core :as nrepl] '[nrepl.server :as server])
(with-open [srv (server/start-server :port 0)
            conn (nrepl/connect :port (:port srv))]
  (let [client (nrepl/client conn 60000)
        values (fn [msg] (->> (nrepl/message client msg) (keep :value) vec))
        check (fn [session sym]
                (values {:op "eval" :session session
                         :code (format "(defn %s []) [*file* (select-keys (meta #'%s) [:file :line])]" sym sym)}))]
    (let [session (-> (nrepl/message client {:op "clone"}) first :new-session)]
      (prn :eval-before (check session "f1"))
      (prn :eval-with-file (values {:op "eval" :session session :file "/tmp/x.clj" :code "*file*"}))
      (prn :eval-after (check session "f2")))
    ;; load-file's :file is the file's contents, :file-path its path.
    (let [session (-> (nrepl/message client {:op "clone"}) first :new-session)]
      (prn :load-file (values {:op "load-file" :session session :file "*file*"
                               :file-path "/tmp/y.clj" :file-name "y.clj"}))
      (prn :load-file-after (check session "f3")))))
(shutdown-agents)
:eval-before ["#'user/f1" "[\"NO_SOURCE_PATH\" {:file \"NO_SOURCE_PATH\", :line 1}]"]
:eval-with-file ["\"/tmp/x.clj\""]
:eval-after ["#'user/f2" "[\"/tmp/x.clj\" {:file \"/tmp/x.clj\", :line 1}]"]
:load-file ["\"/tmp/y.clj\""]
:load-file-after ["#'user/f3" "[\"/tmp/y.clj\" {:file \"/tmp/y.clj\", :line 1}]"]

Environment & Version information

Clojure version

1.12.5 (nREPL 1.8.0, master is the same)

Java version

21

Operating system

macOS 26.6

Dominant language
Clojure
Stars
907
Forks
111
Avg merge
8d 10h
Merged PRs (30d)
7

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nrepl/nrepl

All issues in nrepl/nrepl

Similar issues

More Clojure issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.