This had me perplexed. I have a PowerShell script that calls Docker and passes in some build arguments like this:

docker build --secret id=npm,src=$($env:USERPROFILE)/.npmrc --progress=plain -t imagename .

But it was failing with this error:

ERROR: failed to stat $($env:USERPROFILE)/.npmrc: CreateFile $($env:USERPROFILE)/.npmrc: The filename, directory name, or volume label syntax is incorrect.

It should be evaluating the $($env:USERPROFILE) expression to the current user's profile/home directory, but it isn't.

Is there some recent breaking change in how PowerShell evaluates arguments to a native command? I skimmed the release notes but nothing jumped out.

I know you can use the "stop-parsing token" --% to stop PowerShell from interpreting subsequent text on the line as commands or expressions, but I wasn't using that.

In fact the whole about_Parsing documentation is a good read to understand the different modes and how PowerShell passes arguments to native and PowerShell commands. But I still couldn't figure it out.

So what's going on?

Another tool I find useful when trying to diagnose issues with passing arguments is EchoArgs. It too reported the argument was not being evaluated.

But then I noticed something curious on the command line:

Screenshot of echoargs command line with comma separating arguments in grey colour

That comma is being rendered in my command line in grey, but the rest of the arguments are white (with the exception of the variable expression). Could that be the problem?

Let's try enclosing the arguments in double quotes..

docker build --secret "id=npm,src=$($env:USERPROFILE)/.npmrc" --progress=plain -t imagename .

Notice the colours on the command line - the comma is not different now:

Screenshot of echo args command line, now with double quotes and the comma not in a different colour

And the colouring on the command line also hints that it is not treating the comma as something special.

And now our Docker command works!