Yeachan-Heo/oh-my-codex · error
${path} must be a non-empty string array
Error message
${path} must be a non-empty string array What it means
validateStringArray requires an array where every element is a non-empty, non-whitespace string. It is used to validate answer.selected_values and answer.selected_labels on submitted question answers; anything else (non-array, empty array elements, blanks, numbers) throws with the offending path.
Source
Thrown at src/question/state.ts:298
}
}
try {
return await fn();
} finally {
try {
const currentOwner = await readFile(ownerPath, 'utf8');
if (currentOwner.trim() === ownerToken) {
await rm(lockDir, { recursive: true, force: true });
}
} catch {
}
}
}
function validateStringArray(value: unknown, path: string): string[] {
if (!Array.isArray(value) || !value.every((item) => typeof item === 'string' && item.trim().length > 0)) {
throw new Error(`${path} must be a non-empty string array`);
}
return value;
}
function assertNoDuplicateValues(values: string[], path: string): void {
const seen = new Set<string>();
for (const value of values) {
if (seen.has(value)) throw new Error(`${path} must not contain duplicate values: ${value}`);
seen.add(value);
}
}
function expectedSelectedLabelsForValues(
question: NormalizedQuestionItem,
selectedValues: string[],
otherText: string | undefined,
): string[] {
const optionLabelsByValue = new Map(question.options.map((option) => [option.value, option.label]));View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Ensure selected_values and selected_labels are always arrays of trimmed, non-empty strings before submit
- Filter out empty/blank entries: values.map(v => v.trim()).filter(Boolean)
- Add a client-side schema check (e.g. zod) mirroring: array of non-empty strings
Example fix
// before answer.selected_values = rawInput; // could be '' or undefined // after answer.selected_values = (Array.isArray(rawInput) ? rawInput : [rawInput]).map((v) => String(v).trim()).filter((v) => v.length > 0);
Defensive patterns
Strategy: validation
Validate before calling
function isNonEmptyStringArray(v: unknown): v is string[] {
return Array.isArray(v) && v.every((x) => typeof x === 'string' && x.trim().length > 0);
}
if (!isNonEmptyStringArray(answer.selected_values)) throw new Error('bad selected_values'); Type guard
function isNonEmptyStringArray(v: unknown): v is string[] {
return Array.isArray(v) && v.every((x) => typeof x === 'string' && x.trim().length > 0);
} Try / catch
try { await submit(recordPath, answers); } catch (e) { if (/must be a non-empty string array/.test((e as Error).message)) { highlightInvalidField((e as Error).message); return; } throw e; } Prevention
- Normalize and trim user selections before building the answer
- Mirror the array-of-nonempty-strings rule with a client-side schema (zod/json-schema)
When it happens
Trigger: Submitting an answer whose selected_values or selected_labels is undefined, not an array, contains empty strings, whitespace-only strings, or non-string values; e.g. answers[i].answer.selected_values = [] is fine only if length checks elsewhere pass, but [''] or 'opt1' (a bare string) throw here.
Common situations: Clients building answers from raw form state without normalizing empty inputs; JSON payloads where a single select sends a scalar instead of a 1-element array; trimming side effects producing '' after whitespace-only input.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- selected value is not in the option schema: ${value}
- ${path} cardinality must match selected values
- ${path}[${mismatchIndex}] must match the selected value labe
- answers[${entry.index}].question_id is unknown for this ques
- answers[${entry.index}].answer.kind=other is not allowed for
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/ff9277b6480d0e2a.
Report an issue: GitHub.