clojure/clojure · error · java.lang.UnsupportedOperationException

Unknown Collection type

Error message

Unknown Collection type

What it means

Compiler.emitConstantsAsStatic or a similar emit path throws this UnsupportedOperationException when emitting a constant collection literal it cannot map to a known collection interface. The Clojure compiler only knows how to emit constants for vectors (IPersistentVector), maps (IPersistentMap), and sets (IPersistentSet); any other Collection subtype falls into the final else and throws. It indicates an internal compiler gap, not user code error, unless custom collection types are involved.

Solutions

  1. Ensure the compile-time constant value is one of the supported types: vector, map, or set (e.g. wrap with (vec coll) or (into {} ...))
  2. Check custom data readers/macro return values and normalize them to core collections
  3. If implementing a custom IPersistentCollection, add support in the compiler or avoid it in constant position
  4. File/inspect upstream issue since this is an internal invariant violation in clojure.lang.Compiler

Example fix

// before: custom collection as constant
(def c (MyCustomColl. [1 2 3]))
// after: normalize to a core vector
(def c (vec (MyCustomColl. [1 2 3])))
Defensive patterns

Strategy: type-guard

Validate before calling

(defn supported-constant? [c]
  (or (vector? c) (map? c) (set? c)))
;; normalize before using as compile-time constant
(when-not (supported-constant? c) (throw (ex-info "unsupported constant coll" {:v c})))

Type guard

(defn ->supported-coll [c]
  (cond (vector? c) c (map? c) c (set? c) c :else (vec c)))

Try / catch

(try
  (compile-or-load ns)
  (catch UnsupportedOperationException e
    (when-not (re-find #"Unknown Collection type" (.getMessage e)) (throw e))
    (log/warn "unsupported constant collection in compiled ns")))

Prevention

When it happens

Trigger: A constant expression whose value is a Collection that is not an IPersistentVector, IPersistentMap, or IPersistentSet is emitted at compile time — e.g. via a custom IPersistentCollection implementation, a macro returning an exotic collection, or a data reader producing one.

Common situations: Using custom transient/record-like collections as compile-time constants; data readers (e.g. custom tagged literals) returning non-standard collection types that end up in constants; unusual interop objects embedded via macros.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of clojure/clojure@f3b143341d (2026-09-09). Data as JSON: /api/errors/fcae2fcb1d4954f3. Report an issue: GitHub.

Appendix: source

Thrown at src/jvm/clojure/lang/Compiler.java:3499

	public EmptyExpr(Object coll){
		this.coll = coll;
	}

	public Object eval() {
		return coll;
	}

	public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
		if(coll instanceof IPersistentList)
			gen.getStatic(LIST_TYPE, "EMPTY", EMPTY_LIST_TYPE);
		else if(coll instanceof IPersistentVector)
			gen.getStatic(VECTOR_TYPE, "EMPTY", VECTOR_TYPE);
		else if(coll instanceof IPersistentMap)
				gen.getStatic(HASHMAP_TYPE, "EMPTY", HASHMAP_TYPE);
			else if(coll instanceof IPersistentSet)
					gen.getStatic(HASHSET_TYPE, "EMPTY", HASHSET_TYPE);
				else
					throw new UnsupportedOperationException("Unknown Collection type");
		if(context == C.STATEMENT)
			{
			gen.pop();
			}
	}

	public boolean hasJavaClass() {
		return true;
	}

	public Class getJavaClass() {
		if(coll instanceof IPersistentList)
			return IPersistentList.class;
		else if(coll instanceof IPersistentVector)
			return IPersistentVector.class;
		else if(coll instanceof IPersistentMap)
				return IPersistentMap.class;
			else if(coll instanceof IPersistentSet)

View on GitHub (pinned to f3b143341d)