clojure/clojure · error · RuntimeException
Can't create defs outside of current ns
Error message
Can't create defs outside of current ns
What it means
def always creates the var in the current namespace. If a def names a qualified symbol that resolves to an existing var belonging to a different namespace, interning would mutate someone else's namespace, so the compiler refuses with this error (the old "name conflict" message is commented out in the source).
Solutions
- Drop the qualifier and def an unqualified symbol in the current namespace, or use a new name to avoid confusion.
- If you truly need to set a var in another namespace, use (intern 'other.ns 'var-name value) or eval inside (in-ns 'other.ns).
- If you wanted to change the value of the existing var, use alter-var-root (e.g. (alter-var-root #'other.ns/v (constantly new-v))) instead of def.
Example fix
// before
(def clojure.test/*report-counters* {}) ; foreign ns
// after
(alter-var-root #'clojure.test/*report-counters* (constantly {})) Defensive patterns
Strategy: fallback
Validate before calling
(let [v (resolve sym)]
(when (and v (not= (ns-name (:ns (meta v))) (ns-name *ns*)))
(println "var belongs to another ns; use intern or alter-var-root"))) Try / catch
try {
(eval form)
} catch (RuntimeException e) {
(if (.contains (.getMessage e) "outside of current ns")
(intern (symbol (namespace target-sym)) (symbol (name target-sym)) value)
(throw e))
} Prevention
- def only unqualified symbols in the current namespace.
- Use intern to create vars in other namespaces, alter-var-root to change existing ones.
- Keep code generation emitting plain symbol names.
When it happens
Trigger: Evaluating (def some.other.ns/existing-var v) where the var exists but its namespace is not the current *ns* and the symbol carries an explicit ns qualifier (the sym.ns == null intern path is skipped).
Common situations: Attempting to override a library var via its fully qualified name; generated code that emits qualified def names; after renaming/moving code so an old qualified def now points at a foreign ns.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Can't refer to qualified var that doesn't exist
- Can't let qualified name:
- Can't use qualified name as parameter:
- Unable to resolve var: " + sym + " in this context
- ArityException
AI-assisted analysis of clojure/clojure@f3b143341d (2026-09-09).
Data as JSON: /api/errors/973acd084841cbde.
Report an issue: GitHub.
Appendix: source
Thrown at src/jvm/clojure/lang/Compiler.java:554
else if(RT.count(form) < 2)
throw Util.runtimeException("Too few arguments to def");
else if(!(RT.second(form) instanceof Symbol))
throw Util.runtimeException("First argument to def must be a Symbol");
Symbol sym = (Symbol) RT.second(form);
Var v = lookupVar(sym, true);
if(v == null)
throw Util.runtimeException("Can't refer to qualified var that doesn't exist");
if(!v.ns.equals(currentNS()))
{
if(sym.ns == null)
{
v = currentNS().intern(sym);
registerVar(v);
}
// throw Util.runtimeException("Name conflict, can't def " + sym + " because namespace: " + currentNS().name +
// " refers to:" + v);
else
throw Util.runtimeException("Can't create defs outside of current ns");
}
IPersistentMap mm = sym.meta();
boolean isDynamic = RT.booleanCast(RT.get(mm,dynamicKey));
if(isDynamic)
v.setDynamic();
if(!isDynamic && sym.name.startsWith("*") && sym.name.endsWith("*") && sym.name.length() > 2)
{
RT.errPrintWriter().format("Warning: %1$s not declared dynamic and thus is not dynamically rebindable, "
+"but its name suggests otherwise. Please either indicate ^:dynamic %1$s or change the name. (%2$s:%3$d)\n",
sym, SOURCE_PATH.get(), LINE.get());
}
if(RT.booleanCast(RT.get(mm, arglistsKey)))
{
IPersistentMap vm = v.meta();
//vm = (IPersistentMap) RT.assoc(vm,staticKey,RT.T);
//drop quote
vm = (IPersistentMap) RT.assoc(vm,arglistsKey,RT.second(mm.valAt(arglistsKey)));
v.setMeta(vm);View on GitHub (pinned to f3b143341d)