Change:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --Steps to Reproduce: created this simple snippet: I expand the snippet, I get this: Expected this: It uses the first variable as a part of the placeholder of the second variable. The second occurrence of the second variable is not substituted properly. !
Confirmed... Looks like we capture the value of 1 "replication". For now you can workaround by "inlining" the second occurrence of $1, e.g have two times

Discussion:
return true; }); <del> for (const placeholder of incompletePlaceholders) { </del> <ins> const fillInIncompletePlaceholder = (placeholder: Placeholder, stack: Set<number>) => { </ins> const defaultValues = placeholderDefaultValues.get(placeholder.index); <del> if (defaultValues) { const clone = new Placeholder(placeholder.index); clone.transform = placeholder.transform; for (const child of defaultValues) { clone.appendChild(child.clone()); </del> <ins> if (!defaultValues) { return; } const clone = new Placeholder(placeholder.index); clone.transform = placeholder.transform; for (const child of defaultValues) { const newChild = child.clone(); clone.appendChild(newChild); // "recurse" on children that are again placeholders if (newChild instanceof Placeholder && placeholderDefaultValues.has(newChild.index) && !stack.has(newChild.index)) { stack.add(newChild.index); fillInIncompletePlaceholder(newChild, stack); stack.delete(newChild.index); </ins> } <del> snippet.replace(placeholder, [clone]); </del> } <ins> snippet.replace(placeholder, [clone]); }; const stack = new Set<number>(); for (const placeholder of incompletePlaceholders) { fillInIncompletePlaceholder(placeholder, stack); </ins> } return snippet.children.slice(offset);

assert.strictEqual((<FormatString>variable.transform!.children[0]).ifValue, ''); assert.strictEqual((<FormatString>variable.transform!.children[0]).elseValue, undefined); }); <ins> test('Snippet placeholder empty right after expansion #152553', function () { const snippet = new SnippetParser().parse('${1:prog}: ${2:$1.cc} - $2'); const actual = snippet.toString(); assert.strictEqual(actual, 'prog: prog.cc - prog.cc'); const snippet2 = new SnippetParser().parse('${1:prog}: ${3:${2:$1.cc}.33} - $2 $3'); const actual2 = snippet2.toString(); assert.strictEqual(actual2, 'prog: prog.cc.33 - prog.cc prog.cc.33'); // cyclic references of placeholders const snippet3 = new SnippetParser().parse('${1:$2.one} <> ${2:$1.two}'); const actual3 = snippet3.toString(); assert.strictEqual(actual3, '.two.one.two.one <> .one.two.one.two'); }); </ins> });