{"record":{"id":"206c1e1fcc47d23e","repo":"clojure/clojure","slug":"metadata-can-only-be-applied-to-imetas-206c1e","errorCode":null,"errorMessage":"Metadata can only be applied to IMetas","messagePattern":"Metadata can only be applied to IMetas","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/jvm/clojure/lang/LispReader.java","lineNumber":986,"sourceCode":"\t\t\tif(line != -1 && o instanceof ISeq)\n\t\t\t\t{\n\t\t\t\tmeta = RT.assoc(meta, RT.LINE_KEY, RT.get(meta, RT.LINE_KEY, line));\n\t\t\t\tmeta = RT.assoc(meta, RT.COLUMN_KEY, RT.get(meta,RT.COLUMN_KEY, column));\n\t\t\t\t}\n\t\t\tif(o instanceof IReference)\n\t\t\t\t{\n\t\t\t\t((IReference)o).resetMeta((IPersistentMap) meta);\n\t\t\t\treturn o;\n\t\t\t\t}\n\t\t\tObject ometa = RT.meta(o);\n\t\t\tfor(ISeq s = RT.seq(meta); s != null; s = s.next()) {\n\t\t\tIMapEntry kv = (IMapEntry) s.first();\n\t\t\tometa = RT.assoc(ometa, kv.getKey(), kv.getValue());\n\t\t\t}\n\t\t\treturn ((IObj) o).withMeta((IPersistentMap) ometa);\n\t\t\t}\n\t\telse\n\t\t\tthrow new IllegalArgumentException(\"Metadata can only be applied to IMetas\");\n\t}\n\n}\n\npublic static class SyntaxQuoteReader extends AFn{\n\tpublic Object invoke(Object reader, Object backquote, Object opts, Object pendingForms) {\n\t\tPushbackReader r = (PushbackReader) reader;\n\t\ttry\n\t\t\t{\n\t\t\tVar.pushThreadBindings(\n\t\t\t\t\tRT.map(GENSYM_ENV, PersistentHashMap.EMPTY));\n\n\t\t\tObject form = read(r, true, null, true, opts, ensurePending(pendingForms));\n\t\t\treturn syntaxQuote(form);\n\t\t\t}\n\t\tfinally\n\t\t\t{\n\t\t\tVar.popThreadBindings();","sourceCodeStart":968,"sourceCodeEnd":1004,"githubUrl":"https://github.com/clojure/clojure/blob/f3b143341d6efc6428b523b2eaa099a6cc99156e/src/jvm/clojure/lang/LispReader.java#L968-L1004","documentation":"Thrown by MetaReader after successfully reading metadata when the object it decorates does not implement IMeta. Only symbols, collections, and other IMeta instances can carry metadata; numbers, strings read as literals of non-IMeta types, and other objects cannot. The reader rejects applying ^meta to such a form.","triggerScenarios":"Reading ^{:doc \"x\"} 5 or ^:foo [1 2 3] is fine (vectors are IMeta), but ^:foo 42, ^:foo \"str\" (String is not IMeta in the host), or ^:foo 3.14 trigger it.","commonSituations":"Attaching type hints to numbers/strings hoping for optimization; macro-generated code that applies metadata to literal values; confusion about which host types implement IMeta.","solutions":["Move the metadata to an IMeta target: a symbol (def name ^meta val), or a collection.","If you need the value itself tagged, bind it to a named symbol and put metadata there, e.g. (def x ^{:v 1} 42) — metadata on def's symbol.","Use with-meta only on IObj/IMeta values; restructure code that decorates raw literals."],"exampleFix":"// before\n(defn f [] ^{:deprecated true} 42)\n// after\n(def answer ^{:deprecated true} 42)\n(defn f [] answer)","handlingStrategy":"type-guard","validationCode":"// only apply reader metadata to IMeta targets\nfunction canTakeMeta(o) {\n  return o instanceof IObj; // IObj extends IMeta\n}","typeGuard":"function isIMeta(o) {\n  return o instanceof IMeta;\n}","tryCatchPattern":"try {\n  readOrEval(src);\n} catch (IllegalArgumentException e) {\n  if (\"Metadata can only be applied to IMetas\".equals(e.getMessage())) {\n    // move metadata to a symbol or collection\n  } else throw e;\n}","preventionTips":["Never attach ^meta to numbers, strings, or other non-IMeta literals.","Put metadata on the def symbol or on collections instead.","Check IMeta before calling with-meta in generated code."],"tags":["clojure","reader","metadata","type-constraint"],"backgroundTag":"type-mismatch","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"}