diff --git a/app/src/lib/validation/variable-schema.ts b/app/src/lib/validation/variable-schema.ts index ab1e5be..411e940 100644 --- a/app/src/lib/validation/variable-schema.ts +++ b/app/src/lib/validation/variable-schema.ts @@ -7,7 +7,12 @@ function fieldSchema(variable: VariableConfig): z.ZodTypeAny { switch (variable.type) { case "string": { let s = z.string(); - if (variable.minLength !== undefined) s = s.min(variable.minLength); + // `required` alone has to reject "" even when the author didn't set an explicit + // minLength - otherwise an empty string satisfies a bare z.string() and the run starts + // with a "required" field effectively unset. + const minLength = + variable.minLength ?? (variable.required ? 1 : undefined); + if (minLength !== undefined) s = s.min(minLength); if (variable.maxLength !== undefined) s = s.max(variable.maxLength); if (variable.pattern) s = s.regex(new RegExp(variable.pattern)); field = s; @@ -26,9 +31,12 @@ function fieldSchema(variable: VariableConfig): z.ZodTypeAny { case "enum": field = z.enum(variable.choices as [string, ...string[]]); break; - case "multiselect": - field = z.array(z.enum(variable.choices as [string, ...string[]])); + case "multiselect": { + let arr = z.array(z.enum(variable.choices as [string, ...string[]])); + if (variable.required) arr = arr.min(1); + field = arr; break; + } } if (!variable.required) {