Your first question is that you're probably missing how the sequence of evaluation occurs, specifically that the expression f1[{{a, b}, {c, d}, {e, f}}, x] will be evaluated before the rules for Thread are applied. I.e. Thread[f1[{{a, b}, {c, d}, {e, f}}, x]] evaluates to Thread[{{a, b}, {c, d}, {e, f}, x}] before continuing on to result in {{a, c, e, x}, {b, d, f, x}}.
As for your second question, I'll need to make some assumptions about how you're getting to this point in your program. Since you're trying to evaluate this expression:
Thread[f1[{{a, b}, {c, d}, {e, f}}, x]]
then you must at some point have been able to assemble your desired arguments {{a, b}, {c, d}, {e, f}} and x already. So, you could just as easily have put them together in a list:
{{{a, b}, {c, d}, {e, f}}, x}
If you can do that, then all you need to do now is use MapApply after Threading:
f1 @@@ Thread[{{{a, b}, {c, d}, {e, f}}, x}] (* {{a, b, x}, {c, d, x}, {e, f, x}} *)
(Assuming your definition for f1)
If for some reason you really want the f1 in your structure prior to Threading, then you could first inactivate it and then activate it afterward:
Thread[Inactive[f1][{{a, b}, {c, d}, {e, f}}, x]] // Activate
If we knew more about the provenance of your individual arguments, we might have more suggestions.
jo = Join[{{a, b}, {c, d}, {e, f}}, {x}]; Thread[jo]$\endgroup$Traceto see the evaluation order.Threaddoes not have any hold attributes, which means thatf1is evaluated first, and only thenThreadcomes into play. $\endgroup$f1[inp1_, inp2_] := Join[inp1, inp2]; Thread[f1[{{a, b}, {c, d}, {e, f}}, x]] /. x -> {x}to have your expected output. $\endgroup$Thread[f[{{a, b}, {c, d}, {e, g}}, x]]and (2)Thread[f[{a, b}, {c, d}, {e, g}, x]]. Note the different structure of the arguments tof. So you shouldn't expect the same output. $\endgroup$Thread, however. It evaluates its arguments before doing the threading". And "Here is a trick for getting around this type of problem that every Mathematica programmer should know about:Unevaluatedmay be wrapped around any argument to a function to pass the unevaluated form of the argument to the function" For example (Wagner)Thread[Unevaluated[Equal[{1, 2, 3}, {1, 2, 4}]]](as @Michael E2 has pointed out in a comment for the OP example) $\endgroup$