code: @Override
      AbstractConfigValue resolveSubstitutions(ResolveContext context) {
          context.source().replace(this, ResolveReplacer.cycleResolveReplacer);
          try {
              AbstractConfigValue v;
              try {
                  v = context.source().lookupSubst(context, expr, prefixLength);
              } catch (NotPossibleToResolve e) {
                  if (expr.optional())
                      v = null;
                  else
                      throw new ConfigException.UnresolvedSubstitution(origin(), expr
                              + " was part of a cycle of substitutions involving " + e.traceString(),
                              e);
              }
  
              if (v == null && !expr.optional()) {
                  throw new ConfigException.UnresolvedSubstitution(origin(), expr.toString());
              }
              return v;
          } finally {
              context.source().unreplace(this);
          }
      }
docs: any failure to resolve has to start with a ConfigReference.