Apparently there's two ways to represent a list syntax object: (datum->syntax #'x '(a b c)) => #(syntax-object (a b c) ((top)) (hygiene guile-user)) i.e. a syntax object vector with a list payload, and #'(a b c) => (#(syntax-object a ((top)) (hygiene guile-user)) #(syntax-object b ((top)) (hygiene guile-user)) #(syntax-object c ((top)) (hygiene guile-user))) i.e. a list of the elements as syntax objects. Syntax-case and syntax->datum work fine with both. But when the latter form is used as the first argument to a datum->syntax call, it leads to an error: --- snip scheme@(guile-user)> (datum->syntax #'(x) '(a b c)) ice-9/psyntax.scm:467:4: In procedure datum->syntax: ice-9/psyntax.scm:467:4: In procedure vector-ref: Wrong type argument in position 1 (expecting vector): (#(syntax-object x ((top)) (hygiene guile-user))) Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue. scheme@(guile-user) [1]> --- snip I think I understand the problem: in case of a list of syntax objects, it's ambiguous which one's environment should be used for the newly created syntax object, so it requires it to be an "immediately wrapped" syntax object instead. (By the way, the psyntax sources actually call that argument 'id', hinting that perhaps it's expected to be an identifier, though the other representation works fine.) I have no clue what's the best way to solve this, but if my understanding is correct, it's a fundamental issue with datum->syntax and not a bug, so here's a documentation patch that tries to explain the limitation.