pbakaus/impeccable · error · Error
payload needs an options array
Error message
payload needs an options array
What it means
Thrown by loadRound in serve-question.mjs when the parsed payload is falsy, has no options array, or the options array is empty. The serve-question page renders option cards, so a payload with zero options cannot produce a meaningful round.
Source
Thrown at plugin/skills/impeccable/scripts/serve-question.mjs:341
else raw = fs.readFileSync(0, 'utf8');
// Round state is mutable: a re-roll keeps this server alive and --update
// swaps in the next hand, so payload, options, and the local-image table
// rebuild per round.
let payload;
let options;
let localImages = [];
// Build path (comp-led vs code-led): the payload carries the recorded
// default; the page's toggle updates the live value per session. The server
// owns both so the final ANSWER states the path and whether it was flipped
// even when the round never rendered a toggle.
let buildPathDefault = null;
let liveBuildPath = null;
function loadRound(json) {
const parsed = JSON.parse(json);
if (!parsed || !Array.isArray(parsed.options) || parsed.options.length === 0) {
throw new Error('payload needs an options array');
}
localImages = [];
const imageSrc = (value) => {
if (!value) return null;
if (/^https?:\/\//.test(value)) return value;
const abs = path.resolve(value);
if (!fs.existsSync(abs)) return null;
localImages.push(abs);
return `/img/${localImages.length - 1}`;
};
// Comps stream in after the page is served, so their slots register
// whether or not the file exists yet; /img answers 404 until it lands and
// the page polls the slot. Remote comp URLs pass through untouched.
const compSrc = (value) => {
if (!value) return null;
if (/^https?:\/\//.test(value)) return value;
localImages.push(path.resolve(value));
return `/img/${localImages.length - 1}`;View on GitHub (pinned to d14711ae3d)
Solutions
- Ensure the payload JSON has a non-empty `options` array, e.g. { "options": [{ "id": "a", ... }] }.
- Validate the payload with the schema before piping it to serve-question.
- If the round has no contenders yet, generate them first rather than serving an empty options list.
Example fix
// before
{ "prompt": "redesign", "options": [] }
// after
{ "prompt": "redesign", "options": [{ "id": "a", "hero": "./a.png" }] } Defensive patterns
Strategy: validation
Validate before calling
function hasNonEmptyOptions(payload) {
return Array.isArray(payload?.options) && payload.options.length > 0;
} Type guard
function isServeQuestionPayload(value) {
return value !== null && typeof value === 'object' && Array.isArray(value.options) && value.options.length > 0;
} Try / catch
let parsed;
try {
parsed = JSON.parse(raw);
} catch (err) {
throw new Error('payload is not valid JSON: ' + err.message);
}
if (!isServeQuestionPayload(parsed)) {
throw new Error('payload missing non-empty options array');
} Prevention
- Validate payloads against a JSON schema before piping to serve-question.
- Unit-test the generator's output shape against isServeQuestionPayload.
- Fail fast in the generator when no options are produced instead of emitting an empty list.
When it happens
Trigger: Invoking serve-question with a payload file (or stdin) whose JSON is an object without an `options` key, where options is not an array, or where the array is empty.
Common situations: Payload schema changed between the generator and the server, an empty/placeholder payload was fed in, or a JSON file missing the options field entirely.
Related errors
- config.json must be an object
- config.files (non-empty string array) required
- config.files must contain only non-empty strings
- config.exclude, if present, must be a string array
- config.exclude must contain only non-empty strings
AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13).
Data as JSON: /api/errors/ec36a66df380d965.
Report an issue: GitHub.