Creating a document whose input field is a scalar but not a string — { input: 42 }, { input: true } — with TRANSLATION_PROVIDER set to a Gemini provider throws TypeError: text.replace is not a function.
GenkitTranslator.translate sanitises the text before building the prompt:
const sanitizedText = text
.replace(/\/g, "\\\\")
.replace(/"/g, '\\"')
.replace(/\n/g, " ");
The value arrives straight from the document, so .replace is only defined when it happens to be a string. The throw is caught and reported as a translation error with an onError event, so nothing crashes outright — the document simply never gets translated, and the failure reads as an API error rather than a bad input.
Only the create path reaches this. On update, a non-string, non-object input deletes any existing translations and returns before translation.
The Google provider does not throw client side: the value is passed through @google-cloud/translate as q: [42], a JSON number. What the Translation API does with that has not been checked.
Worth deciding what a non-string scalar should mean — stringify it, skip it the way an empty input is skipped, or reject it with a clear message — and then applying that once at the input boundary so every provider behaves the same.
kits/firestore-translate-text/src/translate/common.ts:84-86
firestore-translate-text/functions/src/translate/common.ts:136-138
Surfaced in #3109.
Creating a document whose input field is a scalar but not a string —
{ input: 42 },{ input: true }— withTRANSLATION_PROVIDERset to a Gemini provider throwsTypeError: text.replace is not a function.GenkitTranslator.translatesanitises the text before building the prompt:The value arrives straight from the document, so
.replaceis only defined when it happens to be a string. The throw is caught and reported as a translation error with anonErrorevent, so nothing crashes outright — the document simply never gets translated, and the failure reads as an API error rather than a bad input.Only the create path reaches this. On update, a non-string, non-object input deletes any existing translations and returns before translation.
The Google provider does not throw client side: the value is passed through
@google-cloud/translateasq: [42], a JSON number. What the Translation API does with that has not been checked.Worth deciding what a non-string scalar should mean — stringify it, skip it the way an empty input is skipped, or reject it with a clear message — and then applying that once at the input boundary so every provider behaves the same.
kits/firestore-translate-text/src/translate/common.ts:84-86firestore-translate-text/functions/src/translate/common.ts:136-138Surfaced in #3109.