As @soegaard's answer shows, the problem isn't specific to syntax/loc: the fundamental issue is that ... can't handle any template term that uses unsyntax (a.k.a. #,), because ... doesn't know how to map the expression over (potentially nested) lists of pattern variables.
FWIW, if you are using syntax-parse, I would use #:with instead of with-syntax.
#lang racket/base
(require (for-syntax racket/base
syntax/parse))
(define-syntax (example stx)
(syntax-parse stx
[(_ (id val) ...)
#:with (rhs ...) (for/list ([val-expr (syntax->list #'(val ...))])
;; do work here ...
(quasisyntax/loc val-expr #,val-expr))
#`(let ([id rhs] ...)
(list id ...))]))
(example [a 1] [b 2]) ; -> '(1 2)
Just to check, are you manipulating the “values” at compile time or at run time?
At compile time, you only have the syntax of the sub-expression (or, more generally, the sub-form): it isn't evaluated until runtime. So you might have #'(+ 1 2) instead of #'3. The best way to detect and report compile-time errors in macro subterms is to use syntax/parse's syntax classes.
If, instead, you are manipulating the actual values at runtime, you should take a look at 1.2.6 Contracts on Macro Sub-expressions.