Page MenuHomePhabricator

Explain why functions are not available in selector (type mismatch)
Closed, ResolvedPublic

Description

Problem statement

Not all functions are available in the Abstract Wikipedia function selector, as availability depends on whether a function’s output type matches the required input type.

This constraint is not visible or explained in the UI. As a result, commonly used functions (e.g. sentence-generating functions) may not appear because their output does not match the expected type (such as HTML).

To use these functions, contributors must apply wrapper functions to make them compatible, but this requirement is not communicated.

Some users therefore assume something is broken and struggle to continue or find the correct approach.

User Impact
  • Users assume missing functions are bugs like here and here
  • Users get blocked, are confused and seek out help (e.g. on Telegram)

Example

User wants to use: Z28109 (“[subject] is the [role] of [dependency]”)

Steps:

  • Open article editor
  • Add empty fragment
  • Search for function Z28109

Result: Function is not available in the selector

How to make it work: Function requires wrappers (e.g. Z27861, Z24159) to be usable

User perception: “This function is missing / broken”

Suggested Approach

Aim for a small UX improvement that reduce confusion without introducing heavy UI or complexity.

Event Timeline

Ideas on my end:

Idea 1 - Effort: Lowest

Add a small inline notice near fragment function selection explaining only functions returning Z89 (HTML Fragment) are valid, so users understand why some functions do not appear.

Screenshot 2026-04-14 at 16.16.50.png (1,198×1,126 px, 143 KB)
simple info message saying only functions that return html/z89 are shown in the selector

Idea 2 - Zid lookup hint - Effort: Low/Medium

When a user types something that looks like a ZID and gets no results, show a targeted message (“exists but incompatible with expected type/return type”)

Screenshot 2026-04-14 at 16.36.53.png (1,184×742 px, 72 KB)
incompatible type

Idea 3 - No-results CTA link - Effort: Low/Medium

When a user types something that looks like a ZID and gets no results, show a link to open that ZID page so they can quickly inspect type/return type.

Screenshot 2026-04-14 at 16.35.45.png (1,186×682 px, 77 KB)
incompatible type & Cta

Idea 4 - Result badges in lookup list: show return type badge (Z89, Z6) and gray out incompatible items with reason - Effort: High

Include non-selectable matches in the dropdown as disabled rows with a short reason (e.g., wrong return type), instead of hiding them completely.
The risk here is that we might return tons of useless results first because they hit the search query as highest score; like functions that return types, functions that are just helper functions and so on. (see second screenshot)

Screenshot 2026-04-14 at 16.42.20.png (1,178×702 px, 71 KB)
Screenshot 2026-04-14 at 16.43.23.png (1,204×1,272 px, 171 KB)
Not compatibleuseless functions returned

Idea 5 - Backend/API-provided mismatch explanations - Effort: Very high

Extend backend/search responses to return structured incompatibility reasons so the frontend can present precise guidance consistently across selector contexts.

RISK: this component is used everywhere inside wikifunctions.org and is a generic component, we should avoid making if elses forever inside this one.

Jdforrester-WMF changed the task status from Open to In Progress.Apr 15 2026, 5:03 PM
Jdforrester-WMF triaged this task as Medium priority.

I think a good solution should do two things: explain why the function is not available in this field, and help the contributor understand what to do next. In the longer term, the ideal experience may be one where incompatibility is handled automatically in the background, for example we show all the functions and if there is any that is incompatible a compatible wrapper function will be automatically added or we show this wrapper suggestions for the contributor to add themselves with 1 click. But since we want a simple solution for now, we can look at this later.

Some improvements to the ideas proposed by @DSmit-WMF :

Idea 1 - Effort: Lowest

Add a small inline notice near fragment function selection explaining only functions returning Z89 (HTML Fragment) are valid, so users understand why some functions do not appear.

Screenshot 2026-04-14 at 16.16.50.png (1,198×1,126 px, 143 KB)
simple info message saying only functions that return html/z89 are shown in the selector

I agree that a short inline explanation is a good starting point, but by itself it only explains the problem and not the next step. A possible improvement would be helper text below the field with a “Learn more” link that explains why some functions do not appear here and what contributors can do instead.

image.png (1,740×1,410 px, 138 KB)

Idea 2/3- Zid lookup hint + No-results CTA link - Effort: Low/Medium

When a user types something that looks like a ZID and gets no results, show a targeted message (“exists but incompatible with expected type/return type”)

Screenshot 2026-04-14 at 16.35.45.png (1,186×682 px, 77 KB)

A targeted message when someone searches for an exact ZID and gets no result seems especially useful, because it gives us a place to explain that the function exists but cannot be used in this field as-is. Though the drawback of this is that the user has to type the exact ZID but this is a good place to give exact next steps like what exact wrapper functions can be used. This could be complex to implement but one idea is to get this information from existing abstract articles by looking at what functions are usually used together. For a simple solution, we could fallback to linking to the wikifunctions page of the function or the Learn more link in idea 1.

Idea 4 - Result badges in lookup list: show return type badge (Z89, Z6) and gray out incompatible items with reason - Effort: High

Include non-selectable matches in the dropdown as disabled rows with a short reason (e.g., wrong return type), instead of hiding them completely.
The risk here is that we might return tons of useless results first because they hit the search query as highest score; like functions that return types, functions that are just helper functions and so on. (see second screenshot)

Screenshot 2026-04-14 at 16.42.20.png (1,178×702 px, 71 KB)
Screenshot 2026-04-14 at 16.43.23.png (1,204×1,272 px, 171 KB)
Not compatibleuseless functions returned

Showing incompatible matches in the results list is attractive because it works for both label search and ZID search. The downside as you said is that it could clutter the results with many functions that cannot actually be selected which can be a pain for when the contributor is not searching for an unsupported function. If we explore this direction, one way to reduce that problem would be a toggle that lets contributors choose between showing only compatible functions and showing all matching functions.

Screenshot 2026-04-23 at 5.37.59 PM.png (966×1,058 px, 121 KB)

Recommendation
Since we are looking for a small UX improvement my recommendation would be a combination of the modified Idea 1 and of Idea 2/3 above: helper text below the function field with a “Learn more” link, plus a more specific message when someone searches for an exact known function that is incompatible with the required type.

image.png (1,740×1,410 px, 138 KB)
Screenshot 2026-04-14 at 16.35.45.png (1,186×682 px, 77 KB)

@gengh and I discussed the options as well, some key takeaways - aligned with @gonyeahialam comments:

  • Option 2/3: interesting idea, main concern: ZID search might only capture the search behaviour of more expert users and would only capture zero result searches
  • Option 4: Could create too much noise in selector
  • Option 1: +1 to @gonyeahialam recommendation for this.
  • We explored one additional display for Option 1:

FunctionOutputtingHTML in Searchbox.png (1,038×720 px, 98 KB)

    • Downside: this does not allow for a "learn more" link option
  • Additional considerations: We could potentially start by only showing this on Abstract Wikipedia so it would not impact the display on Wikifunctions. We could also consider limiting this to the html wrapper level first.

Downside of the placeholder in the input= In some languages the text 'Select function outputting' might be so long that the actual type would be cut off in the input field because of the width it has and you will never see it.

@gengh and I discussed the options as well, some key takeaways - aligned with @gonyeahialam comments:

  • Option 2/3: interesting idea, main concern: ZID search might only capture the search behaviour of more expert users and would only capture zero result searches
  • Option 4: Could create too much noise in selector
  • Option 1: +1 to @gonyeahialam recommendation for this.
  • We explored one additional display for Option 1:

FunctionOutputtingHTML in Searchbox.png (1,038×720 px, 98 KB)

    • Downside: this does not allow for a "learn more" link option
  • Additional considerations: We could potentially start by only showing this on Abstract Wikipedia so it would not impact the display on Wikifunctions. We could also consider limiting this to the html wrapper level first.

Looking at the placeholder option, I think it is useful as a short hint because it communicates the expected output type directly in the field. But I don’t think it gives us enough space to explain the constraint clearly.

The main issue we are trying to solve as explained in the task description is not only “what type of function can be selected here?” but also “why are some functions missing from the selector?” and "what can the contributor do about it". The placeholder can only answer the first question briefly, and in some languages or narrower field widths, even that message may be cut off as mentioned by @DSmit-WMF .

The helper text below the field gives us more room to explain the rule in plain language while still being concise. Even without the “Learn more” link, I think it is clearer because the explanation remains visible and readable while the contributor is using the field. It also addresses issue 1 and 2 above while adding the Learn more link will answer issue 3.

So my recommendation is that we start with helper text below the field as the small UX improvement for this task.

  1. Did we decide to do it for just HTML or are we doing it for every zreference > zobject selector  type field in abstract articles?

In that case we would get something like:
"Only functions that return $1 ($2) are shown here. If a function is missing, check its return type."
Where $1 = the translated label of 'HTML Fragment 'and $2 = the zid.

For the placeholder the message currently suggested reads a bit strange:
" Select a function outputting HTML fragment (Z89)".
" Select a function outputting Function call (Zx)".
" Select a function outputting Boolean (Zx)".

We can but 'an' there but sometimes it might be 'a'. We can also use "a(n)".

  1. Also pls confirm the exact copy.
  1. Do we want the help text to always show?

(sorry I am missing the icon below, ignore that)

{F78670965}{F78670979}
example different typehtml type

Change #1279316 had a related patch set uploaded (by Daphne Smit; author: Daphne Smit):

[mediawiki/extensions/WikiLambda@master] Add helper text and placeholder for ZReference selector in Abstract content

https://gerrit.wikimedia.org/r/1279316

  1. Did we decide to do it for just HTML or are we doing it for every zreference > zobject selector  type field in abstract articles?

In that case we would get something like:
"Only functions that return $1 ($2) are shown here. If a function is missing, check its return type."
Where $1 = the translated label of 'HTML Fragment 'and $2 = the zid.

If editors encounter the same problem in this other cases then we should but we can start with functions and learn from feedback before expanding.

For the placeholder the message currently suggested reads a bit strange:
" Select a function outputting HTML fragment (Z89)".
" Select a function outputting Function call (Zx)".
" Select a function outputting Boolean (Zx)".

We can but 'an' there but sometimes it might be 'a'. We can also use "a(n)".

  1. Also pls confirm the exact copy.

I thought the decision on slack was to only use helper text for this cc @LMorgantini-WMF
Also the current placeholder text gets truncated

  1. Do we want the help text to always show?

As shown below the helper text is going to appear multiple times in an abstract article and can be distracting or make the UI feel cluttered. This could get worse if we show it for other every zreference > zobject selector type fields. We can slightly improve this by shortening the helper text to one sentence as shown on the table below. The 2nd sentence doesn't add much additional info not covered already by the first. We can also remove the info icon to further simplify it.

Current patch 1279316 showing long helper textOne sentence helper textOne sentence helper text with learn more
browser-screenshot-07c168c9-01ae-4e6c-ba1c-ef9198d.png (2,044×1,754 px, 175 KB)
Screenshot 2026-05-05 at 2.33.33 PM.png (2,030×1,734 px, 240 KB)
browser-screenshot-7b2bf0d8-b371-4b7c-9c6b-1a9c94b.png (2,044×1,754 px, 143 KB)

Showing the helper text only when needed
When you open an abstract article in edit mode and open up the functions you will find the helper text repeated multiple times. Shortening the text wouldn't solve this cluttering of the UI completely. As a solution, we can consider showing the helper text only when the function field is empty or being edited. As shown below, this would remove the repeated helper text.

Selecting a functionChanging the selected function
Addingfunction.gif (960×821 px, 144 KB)
editingfucntion.gif (960×448 px, 278 KB)
When selectedZid is empty we show the helperText. When a function has been selected we hide itWhen the text in the field is empty, or no longer matches the label of the currently selected function, we show the helper.

An exploration based on the popover idea @LMorgantini-WMF
A short copy shows as helper text always with more info in a popover. The Learn more button is now 'Can't find your function

Screenshot 2026-05-11 at 6.43.20 PM.png (1,976×1,438 px, 269 KB)
HidenFxPopover.gif (960×699 px, 1 MB)

Sounds good!

  1. Do we decide now to show it only when the field is empty or emptied and for all return types for functions?
  2. and only on abstract or also on wikifunctions?
  3. what page does the 'Can't find your function' ( in tooltip) link to

@DSmit-WMF As a final solution based on latest discussions, when you edit an abstract article,

all the existing filled function fields show only the help togglebutton with a cdx-popover when you click on it,

Screenshot 2026-05-18 at 8.16.03 PM.png (1,774×1,080 px, 196 KB)

when you add a new fragment the function field shows the helper text and the help popover button beside it.
Screenshot 2026-05-18 at 8.16.48 PM.png (1,774×996 px, 160 KB)

The learn more will link to a section in https://abstract.wikipedia.org/w/index.php?title=Help:How_to_create_an_article, after seeing @LMorgantini-WMF ideas for the explaining function wrapping in the Help:How_to_create_an_article i changed the Learn more copy to be 'How to use a function with a different return type'. This is the question most editors will have in their minds and explains exactly what they will see when they follow the link.

Helper text copy: Only functions that return HTML fragment (Z89) are listed.
Popover heading: Why some functions aren't listed
Body: String of monolingual text list expects a function whose return type is String (Z6). Only functions with that return type are shown in the search.
Body variables: $3 expects a function whose return type is $2 ($1). Only functions with that return type are shown in the search.
$3= Parent function (where not available use 'This field')
URL: How to use a function with a different return type

Complete flow

Screen Recording 2026-05-18 at 8.36.45 PM.gif (960×865 px, 1 MB)

There are a few issues with the proposed design:

  1. the label is not equally wide as the selector, so the ( ? ) button will go to the end of the screen which looks off. we need to allow for a bit more space for labels because in some languages they might become longer then the input field.
Screenshot 2026-05-19 at 11.19.06.png (1,240×368 px, 36 KB)
  1. the label + 3dot menu + (?)- button bar is now aware of whatever is selected in the selector, making it hard to hide it whenever no value is selected. But not impossible I think. The label and 2 dots menu are generic independent of any type of selector or value set.
  1. the blue circle with ( ? ) is higher in height then the line height, so if a translation of the helper text would go over 2 lines it will haver a big line height:
Screenshot 2026-05-19 at 11.56.37.png (1,200×516 px, 51 KB)
Screenshot 2026-05-19 at 11.55.02.png (1,196×550 px, 72 KB)

Proposal:
Maybe keep the ( ? ) next to the modeselector?

Screenshot 2026-05-19 at 12.01.07.png (1,140×176 px, 18 KB)

There is also an issue with the copy:
$3 = Parent Function is not what you are defining there. You are using the selected value of the function in the selector as the name of 'This field' which is incorrect. Its just the selected value. So correct is that the 'lead paragraph' expects a function that returns html. And following on that: instead of 'join text-like[..]' this is the parent 'paragraph' function that returns html and that is why the field that has 'join text like [..] as a value should return html.
The selected value has nothing to do with a parent function.

Its hard to explain:
For example, if a field requires HTML output (like a top-level lead section fragment (Lead), the tooltip next to the selected value paragraph says:

“paragraph expects a function whose return type is HTML fragment (Z89).”

But paragraph itself doesn’t expect a function — lead paragraph does.

Then its the same thing again with join text-like[...].

But it’s not join text-like[...] that requires a Z89 return type — it’s paragraph > content.

Solution: I honestly think we should just say 'this field'.

  1. the blue circle with ( ? ) is higher in height then the line height, so if a translation of the helper text would go over 2 lines it will haver a big line height:
Screenshot 2026-05-19 at 11.56.37.png (1,200×516 px, 51 KB)
Screenshot 2026-05-19 at 11.55.02.png (1,196×550 px, 72 KB)

Are you using cdx-toggle-button size=small?

  1. the blue circle with ( ? ) is higher in height then the line height, so if a translation of the helper text would go over 2 lines it will haver a big line height:
Screenshot 2026-05-19 at 11.56.37.png (1,200×516 px, 51 KB)
Screenshot 2026-05-19 at 11.55.02.png (1,196×550 px, 72 KB)

Are you using cdx-toggle-button size=small?

Ah that one is solved then. it works with size small:

Screenshot 2026-05-19 at 12.37.31.png (1,176×448 px, 65 KB)

The copy of the popup it should be:
"This field expects a function that returns <TYPE>", not "<FUNCTION LABEL> expects a function..."

There is also an issue with the copy:
$3 = Parent Function is not what you are defining there. You are using the selected value of the function in the selector as the name of 'This field' which is incorrect. Its just the selected value. So correct is that the 'lead paragraph' expects a function that returns html. And following on that: instead of 'join text-like[..]' this is the parent 'paragraph' function that returns html and that is why the field that has 'join text like [..] as a value should return html.
The selected value has nothing to do with a parent function.

@DSmit-WMF Oh i see my error

There is also an issue with the copy:
$3 = Parent Function is not what you are defining there. You are using the selected value of the function in the selector as the name of 'This field' which is incorrect. Its just the selected value. So correct is that the 'lead paragraph' expects a function that returns html. And following on that: instead of 'join text-like[..]' this is the parent 'paragraph' function that returns html and that is why the field that has 'join text like [..] as a value should return html.
The selected value has nothing to do with a parent function.

@DSmit-WMF Oh i see my error

Fix

Screen Recording 2026-05-19 at 12.04.23 PM.gif (960×865 px, 412 KB)

Prototype: https://1ada-2605-59c1-18d1-cc08-c5ba-9ab2-704a-449b.ngrok-free.app/w/index.php?title=Q18336566&action=edit&uselang=en

There is also an issue with the copy:
$3 = Parent Function is not what you are defining there. You are using the selected value of the function in the selector as the name of 'This field' which is incorrect. Its just the selected value. So correct is that the 'lead paragraph' expects a function that returns html. And following on that: instead of 'join text-like[..]' this is the parent 'paragraph' function that returns html and that is why the field that has 'join text like [..] as a value should return html.
The selected value has nothing to do with a parent function.

@DSmit-WMF Oh i see my error

Fix

Screen Recording 2026-05-19 at 12.04.23 PM.gif (960×865 px, 412 KB)

Prototype: https://1ada-2605-59c1-18d1-cc08-c5ba-9ab2-704a-449b.ngrok-free.app/w/index.php?title=Q18336566&action=edit&uselang=en

Sorry, I think my explanation was not good before.
You cant assume that the 'join text-like[..]' function should return the wished return type of the parent. What often happens is the parent (return z89) for example has 2 input fields (for example of type string) that together concat through an implementation to a z89. And when a function is used for the first input fieldm that should return a string because thats the return type of THAT field and not its parent function, which wants a z89 as its output. that comes from concatenating the 2 fields.

So the assumption that you are making with that copy is wrong I think. Like Geno said, we can only assume the return type of THIS field. so the specific field you are selecting a function at. we cant assume anything for parents.

@DSmit-WMF I thought what determines the return type of this field is the function one level above it(if any)

@DSmit-WMF I thought what determines the return type of this field is the function one level above it(if any)

In this specific case they both return a Z89. But the return type of 'content' is defined by content itself, not by its parent. Its just an 'argument' of paragraph.

Here is an example of a multiplication table (z89 return type).
x and y here are natural numbers, they can be functions aswell, but they need to return a natural number. because x and y are arguments of muliplication table and have their own return types.

Screenshot 2026-05-19 at 13.31.13.png (1,194×980 px, 100 KB)

You cant assume that the 'join text-like[..]' function should return the wished return type of the parent. What often happens is the parent (return z89) for example has 2 input fields (for example of type string) that together concat through an implementation to a z89. And when a function is used for the first input fieldm that should return a string because thats the return type of THAT field and not its parent function, which wants a z89 as its output. that comes from concatenating the 2 fields.

Hm there's quite a conceptual mixup, so I'll try to clarify some concepts.

There is no parent function involved here, or at least, not necessarily. If there were a parent function, its output would be totally unrelated and have no effect for this field.

This is what is important for this selector:

  • We know its expected type. In this case it is Z8/function, and it means that the lookup will be selecting a Function.
  • We know the parent expected type. This is the expected type for the parent KEY (not parent function), and just means that whatever we select should end up becoming that type. In this case, it is Z89/html because we are building a fragment and fragments are hardcoded to be Z89/html.

The parent expected type could be given by a number of things (the type of a key of the parent object, the type of an argument of the parent function call, a typed list, a hardcoded type, etc...), and while that's important internally to figure out the parentExpectedType value, it should not affect the message, as it would complicate it without any benefit to the user.

  • The message should only appear when:
    • the selector is set to return functions (i.e. expectedType=Z8)
    • the selector is set to return functions that are bound by type (i.e. parentExpectedType !== Z1) -- so when you can choose any function, this message does not make any sense
  • The copy should not include any function labels (or labels from any parent object),
  • The copy should just communicate the following ideas:
    • this field expects a function that can output an object of type <EXPECTED TYPE>
    • if you cannot find your function in here, it's likely that its output doesn't fit these expectations

Also, from previous conversations:

  • I understand we only want to add this on abstract.wikipedia UI (so no wikifunctions UI)
  • We had also discussed that we would only add this on the top-level function from each fragment, but that decision seems to have been reverted. Is that correct? @LMorgantini-WMF

Change #1279316 merged by jenkins-bot:

[mediawiki/extensions/WikiLambda@master] Add function selector help popover and inline helper text in Abstract content

https://gerrit.wikimedia.org/r/1279316