**Summary**

The root cause of the surprising behaviour is that `Function` does not recognize `Slot[]` when it appears within an association _object_ (as opposed to an association _constructor_).  To fix it, we must either "unwrap" the association object returned by `URLParse` or use a different approach altogether.

**The Problem: Association Objects vs. Association Constructors**

The problem is that the function is being constructed from an association object.  `Function` will not recognize slot references that appear within such objects.

We can demonstrate the problem with a simpler example:

    f = With[{assoc = <| "a" -> #1 |>}, assoc &]
    (* <|"a" -> #1|> & *)

The function definition _looks_ okay.  But it will not work:

    f["hello world!"]
    (* <|"a" -> #1|> *)

We can see the structural difference between an association object and an association constructor using `TreeForm`:

    f // TreeForm
[![association object TreeForm][1]][1]

yet:

    <| "a" -> #1|> & // TreeForm
[![association constructor TreeForm][2]][2]

More discussion on this distinction can be found in [(148095)][3].  See the section labelled _Ambiguity of Association_.

**Fixing the Original Definition**

We can change the original definition to unwrap the association object during the initial evaluation and to recreate it upon use.  We do that using `Normal@URLParse[...]` and `Inactive[URLBuild@*Association]`.  The updated definition looks like this:

    ClearAll[urlModifier];
    urlModifier[url_]:=ReplaceAll[Function@Evaluate[
        Inactive[URLBuild@*Association][
            Normal@URLParse[url]/.{"slot"->Inactive[StringReplace][Slot[1]," "->"_"]}
        ]
    ],{Inactive[x_]:>x}];

... so then:

    urlModifier["https://www.somewebsite.com/path/slot"]["hello world!"]

    (* "https://www.somewebsite.com/path/hello_world%21" *)

**Alternative Definitions**

There are simpler ways to express this operation.

For example, we could define the `urlModifier` operator like this:

    ClearAll[urlModifier]
    
    urlModifier[url_] :=
      URLBuild[URLParse[url] /. {"slot" -> StringReplace[#, " "->"_"]}] &

We could also define it explicitly as a "curried form":

    ClearAll[urlModifier]
    
    urlModifier[url_][s_] :=
      URLBuild[URLParse[url] /. { "slot" -> StringReplace[s," "->"_"]}]

The `Function` form offers an advantage over the curried form in that, if desired, we could perform the initial URL-parsing at the moment of creation instead of every time the generated function is used:

    ClearAll[urlModifier]
    
    urlModifier[url_] :=
      With[{parsedUrl = URLParse[url]}
      , URLBuild[parsedUrl /. {"slot" -> StringReplace[#, " "->"_"]}] &
      ]

All of these definitions give the same results as the corrected original.

  [1]: https://i.sstatic.net/9wVcB.png
  [2]: https://i.sstatic.net/5sUAV.png
  [3]: https://mathematica.stackexchange.com/a/148095/142