{"record":{"id":"72c6be3d79cb0245","repo":"clojure/clojure","slug":"no-reader-function-for-tag-tag","errorCode":null,"errorMessage":"No reader function for tag ${tag}","messagePattern":"No reader function for tag (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/jvm/clojure/lang/LispReader.java","lineNumber":1447,"sourceCode":"\t\t} else {\n\t\t\treturn sym.getName().contains(\".\") ? readRecord(form, sym, opts, pendingForms) : readTagged(form, sym, opts, pendingForms);\n\t\t}\n\n\t}\n\n\tprivate Object readTagged(Object o, Symbol tag, Object opts, Object pendingForms){\n\n\t\tILookup data_readers = (ILookup)RT.DATA_READERS.deref();\n\t\tIFn data_reader = (IFn)RT.get(data_readers, tag);\n\t\tif(data_reader == null){\n\t\tdata_readers = (ILookup)RT.DEFAULT_DATA_READERS.deref();\n\t\tdata_reader = (IFn)RT.get(data_readers, tag);\n\t\tif(data_reader == null){\n\t\tIFn default_reader = (IFn)RT.DEFAULT_DATA_READER_FN.deref();\n\t\tif(default_reader != null)\n\t\t\treturn default_reader.invoke(tag, o);\n\t\telse\n\t\t\tthrow new RuntimeException(\"No reader function for tag \" + tag.toString());\n\t\t}\n\t\t}\n\n\t\treturn data_reader.invoke(o);\n\t}\n\n\tprivate Object readRecord(Object form, Symbol recordName, Object opts, Object pendingForms){\n        boolean readeval = RT.booleanCast(RT.READEVAL.deref());\n\n\t    if(!readeval)\n\t\t    {\n\t\t    throw Util.runtimeException(\"Record construction syntax can only be used when *read-eval* == true\");\n\t\t    }\n\n\t\tClass recordClass = RT.classForNameNonLoading(recordName.toString());\n\n\n\t\tboolean shortForm = true;","sourceCodeStart":1429,"sourceCodeEnd":1465,"githubUrl":"https://github.com/clojure/clojure/blob/f3b143341d6efc6428b523b2eaa099a6cc99156e/src/jvm/clojure/lang/LispReader.java#L1429-L1465","documentation":"When reading a tagged literal `#tag value`, the reader looks up `tag` first in the `data_readers` map (from *data-readers* and data_readers.clj on the classpath), then in `*default-data-reader-fn*`. If neither provides an IFn, it throws RuntimeException \"No reader function for tag <tag>\". This keeps unknown tags from being silently ignored, since the value cannot be constructed.","triggerScenarios":"Reading `#mytag {...}` where `mytag` has no registered data reader: not in *data-readers*, no data_readers.clj on classpath, and *default-data-reader-fn* is nil; also loading an edn/serialized file produced by a different project with custom tags.","commonSituations":"Sharing edn/data files across projects where the consumer lacks the producer's data readers; forgetting to require the namespace that registers the reader; tag renamed between library versions.","solutions":["Bind *data-readers* with a mapping for the tag: `(binding [*data-readers* {'mytag my-fn}] (read-string s))`.","Add a data_readers.clj (or data_readers.cljc) resource on the classpath mapping the tag symbol to a reader function.","Set *default-data-reader-fn* to a fallback handler for unknown tags.","Require the namespace that registers the tag before reading (e.g. via :require in your ns)."],"exampleFix":"// before\n(read-string \"#mytag {:a 1}\")\n;; after\n(binding [*data-readers* {'mytag (fn [v] (->MyTag v))}]\n  (read-string \"#mytag {:a 1}\"))","handlingStrategy":"try-catch","validationCode":"(defn tag-known? [tag]\n  (or (contains? *data-readers* tag)\n      (some? *default-data-reader-fn*)))","typeGuard":null,"tryCatchPattern":"(try\n  (read-string s)\n  (catch RuntimeException e\n    (if (re-find #\"No reader function for tag\" (.getMessage e))\n      (do (require '[my.ns.readers]) (read-string s))\n      (throw e))))","preventionTips":["Register all custom tags in data_readers.clj on the classpath","Require the namespace that defines data readers before reading external data","Provide a *default-data-reader-fn* fallback when reading third-party edn","Document tag schemas alongside data files"],"tags":["clojure","reader","data-reader","edn"],"backgroundTag":"resource-not-found","analyzedSha":"f3b143341d6efc6428b523b2eaa099a6cc99156e","analyzedAt":"2026-09-09T12:04:58.961Z","contentChangedAt":"2026-09-09T12:04:58.961Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}