         entailed = entail ctx, unifiedType.constraints, c
       notDeclared = filter (__ _not, isDeclaredConstraint), checked = (substituteList ctx.substitution, constraints)
       try
-        [deferredConstraints, retainedConstraints] = deferConstraints ctx,
-          notDeclared
-      catch e
-        throw new Error "Error when deferring #{name} #{e.message}"
+      {success, error} = deferConstraints ctx, notDeclared
+      if error
+        throw new Error "Error when deferring #{name} #{error}"
+      [deferredConstraints, retainedConstraints] = success
       if _notEmpty retainedConstraints
         ctx.extendSubstitution substitutionFail "#{name}'s context is too weak, missing #{listOf (map printType, retainedConstraints)}"
   else
     # log name, "constraints", (substituteList ctx.substitution, constraints)
-    [deferredConstraints, retainedConstraints] = deferConstraints ctx,
+    {success, error} = deferConstraints ctx,
       (substituteList ctx.substitution, constraints)
+    if error
+      ctx.extendSubstitution substitutionFail error
+      return
+    [deferredConstraints, retainedConstraints] = success
     # Finalizing type again after possibly added substitution when defer constraints
     currentType = substitute ctx.substitution, type
     # log "assign type", name, (printType (addConstraints currentType, retainedConstraints)), (printType quantifyUnbound ctx, (addConstraints currentType, retainedConstraints))

# Returns deferred and retained constraints
deferConstraints = (ctx, constraints) ->
  reducedConstraints = reduceConstraints ctx, constraints
  throw new Error "could not reduce constraints in deferConstraints" unless reducedConstraints
  fixedVars = ctx.allBoundTypeVariables()
  impliedConstraints = substituteList ctx.substitution, reducedConstraints
  isFixed = (constraint) ->
    # log fixedVars, (printType constraint), (findUnconstrained constraint)
    isSubset fixedVars, (findUnconstrained constraint)
  [deferred, retained] = partition isFixed, impliedConstraints
  # TODO: handle ambiguity when reducedConstraints include variables not in
  # fixedVars or quantifiedVars
  [deferred, retained]

reduceConstraints = (ctx, constraints) ->
  normalized = normalizeConstraints ctx, constraints
  if normalized
    simplifyConstraints ctx, normalized
  else
    null

# Normalized constraints have a type variable in their head, they are "abstract"
# and don't match any one instance

    # if declaredType = ctx.typeForId id
    #   constraintsFromCanonicalType ctx, declaredType, finalType
    # else
      (reduceConstraints ctx, allConstraints).success
  if bare and _notEmpty reducedConstraints
    malformed ctx, expression, "Ambiguous class constraints: #{map safePrintType, reducedConstraints}"
    return "null";
