Problem
An output text field fans out into display fields named ${name}_<lang>, matched by the regex ${name}_[^_]+ (displayFieldPattern) and read back through its inverse displayLangOf, which accepts any key that is ${name}_ followed by an underscore-free remainder. Nothing in validateSearchType stops a sibling field from having such a name.
So a type that declares an output text title beside a field title_tags (any kind) has the sibling read as the display value of title in language tags. parseSearchResponse then yields title: { nl: [...], tags: [...] }, and a surface picking a fallback language renders the sibling’s values as the title. With title_tags declared array: true the misread is a list rather than a string since #824; before that the string guard in localizedValue happened to skip arrays, so the hole only showed for scalar siblings.
The collection definition has the mirror problem: the regex display field title_[^_]+ also matches title_tags in Typesense, which then competes with the sibling’s own declaration for the field’s type and index flag.
Proposal
Reject the declaration in validateSearchType: a field whose name matches an output text sibling’s displayFieldPattern is an error with a message naming both fields, the same way the other physical-name clashes are refused at declaration time rather than surfacing as a misread at query time. The reader stays as it is; the schema is the one place the two names meet.
Found while reviewing #824; predates it.
Problem
An output
textfield fans out into display fields named${name}_<lang>, matched by the regex${name}_[^_]+(displayFieldPattern) and read back through its inversedisplayLangOf, which accepts any key that is${name}_followed by an underscore-free remainder. Nothing invalidateSearchTypestops a sibling field from having such a name.So a type that declares an output text
titlebeside a fieldtitle_tags(any kind) has the sibling read as the display value oftitlein languagetags.parseSearchResponsethen yieldstitle: { nl: [...], tags: [...] }, and a surface picking a fallback language renders the sibling’s values as the title. Withtitle_tagsdeclaredarray: truethe misread is a list rather than a string since #824; before that the string guard inlocalizedValuehappened to skip arrays, so the hole only showed for scalar siblings.The collection definition has the mirror problem: the regex display field
title_[^_]+also matchestitle_tagsin Typesense, which then competes with the sibling’s own declaration for the field’s type and index flag.Proposal
Reject the declaration in
validateSearchType: a field whose name matches an output text sibling’sdisplayFieldPatternis an error with a message naming both fields, the same way the other physical-name clashes are refused at declaration time rather than surfacing as a misread at query time. The reader stays as it is; the schema is the one place the two names meet.Found while reviewing #824; predates it.