Skip to content

Split-Path switches (-Leaf, -Parent, ...) do not work with -LiteralPath #20705

Open

Description

@jantari

Prerequisites

Steps to reproduce

Split-Path -Parent -LiteralPath $env:SystemRoot

Expected behavior

PS> Split-Path -Parent -LiteralPath $env:SystemRoot
C:\

Actual behavior

PS> Split-Path -Parent -LiteralPath $env:SystemRoot
Split-Path: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.

Error details

Exception             :
    Type              : System.Management.Automation.ParameterBindingException
    Message           : Parameter set cannot be resolved using the specified named parameters. One or more parameters issued
cannot be used together or an insufficient number of parameters were provided.
    ErrorId           : AmbiguousParameterSet
    Line              : 1
    Offset            : 1
    CommandInvocation :
        MyCommand        : Split-Path
        BoundParameters  :
            Comparer : System.OrdinalIgnoreCaseComparer
            Count    : 2
            Keys     :
                Length : 6

                Length : 11
            Values   :
                IsPresent : True

                Length      : 1
                LongLength  : 1
                Rank        : 1
                SyncRoot    :
                    Length : 10
                IsFixedSize : True
                Count       : 1
            SyncRoot :
                Comparer : System.OrdinalIgnoreCaseComparer
                Count    : 2
                Keys     :
                    Length : 6

                    Length : 11
                Values   :
                    IsPresent : True

                    Length      : 1
                    LongLength  : 1
                    Rank        : 1
                    SyncRoot    :
                        Length : 10
                    IsFixedSize : True
                    Count       : 1
                SyncRoot :
                    Comparer : System.OrdinalIgnoreCaseComparer
                    Count    : 2
                    Keys     :
                        Length : 6

                        Length : 11
                    Values   :
                        IsPresent : True

                        Length      : 1
                        LongLength  : 1
                        Rank        : 1
                        SyncRoot    :
                            Length : 10
                        IsFixedSize : True
                        Count       : 1
                    SyncRoot :
                        Comparer : System.OrdinalIgnoreCaseComparer
                        Count    : 2
                        Keys     :
                            Length : 6

                            Length : 11
                        Values   :
                            IsPresent : True

                            Length      : 1
                            LongLength  : 1
                            Rank        : 1
                            SyncRoot    :
                                Length : 10
                            IsFixedSize : True
                            Count       : 1
                        SyncRoot :
                            Comparer : System.OrdinalIgnoreCaseComparer
                            Count    : 2
                            Keys     :
                                Length : 6

                                Length : 11
                            Values   :
                                IsPresent : True

                                Length      : 1
                                LongLength  : 1
                                Rank        : 1
                                SyncRoot    :
                                    Length : 10
                                IsFixedSize : True
                                Count       : 1
                            SyncRoot :
                                Comparer : System.OrdinalIgnoreCaseComparer
                                Count    : 2
                                Keys     :
                                    Length : 6

                                    Length : 11
                                Values   :
                                    IsPresent : True

                                    Length      : 1
                                    LongLength  : 1
                                    Rank        : 1
                                    SyncRoot    : …
                                    IsFixedSize : True
                                    Count       : 1
                                SyncRoot :
                                    Comparer : System.OrdinalIgnoreCaseComparer
                                    Count    : 2
                                    Keys     : …
                                    Values   : …
                                    SyncRoot : …
        ScriptLineNumber : 1
        OffsetInLine     : 1
        HistoryId        : 8
        Line             : Split-Path -Parent -LiteralPath $env:SystemRoot
        Statement        : Split-Path -Parent -LiteralPath $env:SystemRoot
        PositionMessage  : At line:1 char:1
                           + Split-Path -Parent -LiteralPath $env:SystemRoot
                           + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        InvocationName   : Split-Path
        PipelineLength   : 1
        PipelinePosition : 1
    ErrorRecord       :
        Exception             :
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Parameter set cannot be resolved using the specified named parameters. One or more parameters issued
cannot be used together or an insufficient number of parameters were provided.
            HResult : -2146233087
        CategoryInfo          : InvalidArgument: (:) [Split-Path], ParentContainsErrorRecordException
        FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.SplitPathCommand
        InvocationInfo        :
            MyCommand        : Split-Path
            ScriptLineNumber : 1
            OffsetInLine     : 1
            HistoryId        : 8
            Line             : Split-Path -Parent -LiteralPath $env:SystemRoot
            Statement        : Split-Path -Parent -LiteralPath $env:SystemRoot
            PositionMessage  : At line:1 char:1
                               + Split-Path -Parent -LiteralPath $env:SystemRoot
                               + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    TargetSite        :
        Name          : ThrowAmbiguousParameterSetException
        DeclaringType : System.Management.Automation.CmdletParameterBinderController, System.Management.Automation,
Version=7.4.0.101, Culture=neutral, PublicKeyToken=31bf3856ad364e35
        MemberType    : Method
        Module        : System.Management.Automation.dll
    Data              : System.Collections.ListDictionaryInternal
    Source            : System.Management.Automation
    HResult           : -2146233087
    StackTrace        :
   at System.Management.Automation.CmdletParameterBinderController.ThrowAmbiguousParameterSetException(UInt32 parameterSetFlags,
MergedCommandParameterMetadata bindableParameters)
   at System.Management.Automation.CmdletParameterBinderController.ValidateParameterSets(Boolean prePipelineInput, Boolean
setDefault)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
   at System.Management.Automation.CommandProcessor.BindCommandLineParameters()
   at System.Management.Automation.CommandProcessor.Prepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
--- End of stack trace from previous location ---
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
   at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][]
pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
CategoryInfo          : InvalidArgument: (:) [Split-Path], ParameterBindingException
FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.SplitPathCommand
InvocationInfo        :
    MyCommand        : Split-Path
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : 8
    Line             : Split-Path -Parent -LiteralPath $env:SystemRoot
    Statement        : Split-Path -Parent -LiteralPath $env:SystemRoot
    PositionMessage  : At line:1 char:1
                       + Split-Path -Parent -LiteralPath $env:SystemRoot
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.0-rc.1
PSEdition                      Core
GitCommitId                    7.4.0-rc.1
OS                             Microsoft Windows 10.0.25992
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

grafik

Activity

  1. added
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    on Nov 16, 2023
  2. jantari commented on Nov 16, 2023

    @jantari
    Author

    Originally reported by Michael Klement (@mklement0) in #8751

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

    Yes I hereby confirm this is still a blocker for me.

  3. 237dmitry commented on Nov 16, 2023

    @237dmitry

    This is because the parameters must be in the parameter set in which they are specified. As you can see, Parent is not in the list of available options:

    $ (gcm Split-Path).ParameterSets.where{ $_.Name -eq 'LiteralPathSet' }.Parameters.Name
    LiteralPath
    Resolve
    Credential
    Verbose
    Debug
    ErrorAction
    WarningAction
    InformationAction
    ProgressAction
    ErrorVariable
    WarningVariable
    InformationVariable
    OutVariable
    OutBuffer
    PipelineVariable
  4. mklement0 commented on Nov 16, 2023

    @mklement0
    Contributor

    Good to know the technical reason for the bug, 237dmitry, but the point is that it is a bug: there is no conceivable reason not to allow the combination of -LiteralPath with either -Parent or -Leaf.

    (As noted in the original issue (#8751), using -Path is a workaround, because Split-Path treats -Path and -LiteralPath arguments the same; also, for -Parent only, simply omitting it with -LiteralPath is an option, given that the -Parent functionality is the default one, e.g. Split-Path -LiteralPath $HOME)

  5. 237dmitry commented on Nov 16, 2023

    @237dmitry

    but the point is that it is a bug: there is no conceivable reason not to allow the combination of -LiteralPath with either -Parent or -Leaf

    They are incompatible with each other due to the design of the cmdlet. Can this be considered a bug? Probably only from the point of view of what the authors meant by such sets of parameters. In my opinion this is rather a feature request.

  6. jantari commented on Nov 16, 2023

    @jantari
    Author

    Any bug can be considered "design" because it's always technically coded to behave that way. But if it makes no sense, goes against expectations, there's no good reason for the behavior and it likely wasn't intended by the authors - then it becomes a bug.

  7. 237dmitry commented on Nov 16, 2023

    @237dmitry

    Any bug can be considered "design"

    No, because with proper syntax you won't get error.

  8. mklement0 commented on Nov 16, 2023

    @mklement0
    Contributor

    237dmitry, what you're arguing about is a fruitless distraction (yes, you can avoid the bug and choose to call it "proper syntax", using the circular argument that the current implementation is ipso facto by design).
    If you oppose the behavior this issue calls for - whatever you choose to label that call as - argue that.
    If, by contrast, your concern is that the - legitimate - concern raised by this issue will not be heard unless properly classified - argue that.

  9. 237dmitry commented on Nov 17, 2023

    @237dmitry

    argue that

    • With proper syntax there are no errors.
    • This is not a bug because you should read the docs & mans.

    Ask the developers why they decided that -LiteralPath does not need to have the same functionality as -Path? Let them argue.

  10. mklement0 commented on Nov 17, 2023

    @mklement0
    Contributor
    • If there is design intent, they will tell us - you don't know, and it is pointless to make yourself the defender of such speculative intent.
      • The syntax diagram in the docs are generated from the implementation, and contain nothing beyond that speaks to the intent that you speculate about.
    • Even if there is design intent: By all appearances, as argued, the cmdlet's behavior doesn't make sense (and is self-contradictory), so whether there was design intent is ultimately irrelevant - unless someone can come up with a good rationale for it; your circular reasoning does not constitute a rationale.
      • In the absence of a good rationale, the only other reason not to make a change would be the need to maintain backward compatibility, and that is not a concern here.
  11. 237dmitry commented on Nov 17, 2023

    @237dmitry

    In my opinion this is rather a feature request.

    so whether there was design intent is ultimately irrelevant - unless someon can come up with a good rationale for it; your circular reasoning does not constitute a rationale.

    What is your circular reasoning, is this a bug or bad design? I think this is the second.

    And, what is for -LiteralPath in this cmdlet at all? This works correctly:

    sp

  12. TobiasPSP commented on Nov 17, 2023

    @TobiasPSP
    Collaborator

    Cmdlets should be intuitive to use. When there is no technical reason why a given parameter should not work in a specific parameterset, then adding it to the parameterset seems an easy fix. I‘ll take this issue to the cmdlet working group for discussion.

  13. mklement0 commented on Nov 17, 2023

    @mklement0
    Contributor

    Thank you, Dr. Tobias Weltner (@TobiasPSP).

    The fix should indeed be simple; to spell it out: add all switches such as -Parent to the LiteralPathSet parameter set.

    (I got myself confused earlier regarding the -Resolve switch: it resolves paths to full paths, but (sensibly) supports wildcard resolution only with -Path, not also with -LiteralPath (which sensibly only resolves literally matching paths to full paths), so making -LiteralPath an alias of -Path isn't an option, even though without -Resolve it effectively is)

  14. 237dmitry commented on Nov 17, 2023

    @237dmitry

    Cmdlets should be intuitive to use. When there is no technical reason why a given parameter should not work in a specific parameterset, then adding it to the parameterset seems an easy fix. I‘ll take this issue to the cmdlet working group for discussion.

    I absolutely agree with you, thank you.

  15. 4 remaining items

  16. SteveL-MSFT commented on Dec 6, 2023

    @SteveL-MSFT
    Member

    @PowerShell/wg-powershell-cmdlets reviewed this. -LiteralPath in all cases should work with the same set of parameters that -Path would accept (excluding some potential edge cases) as its intent is to allow an easier way to specify characters that shouldn't be interpreted. The only concern is the complexity of untangling the parametersets to ensure no regression. However, we agreed that the other switches should work with -LiteralPath

  17. added
    Issue-BugIssue has been identified as a bug in the product
    WG-ReviewedA Working Group has reviewed this and made a recommendation
    and removed
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    on Dec 6, 2023
  18. jantari commented on Jun 4, 2024

    @jantari
    Author

    bump....

  19. jantari commented on Dec 2, 2024

    @jantari
    Author

    activity

    Yes this is obviously still an issue.

  20. jantari commented on Jun 1, 2025

    @jantari
    Author

    activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    In-PRIndicates that a PR is out for the issueIssue-BugIssue has been identified as a bug in the productKeepOpenThe bot will ignore these and not auto-closeWG-Cmdletsgeneral cmdlet issuesWG-ReviewedA Working Group has reviewed this and made a recommendation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions