can1357/oh-my-pi · error · Error
Ask question index exceeded the requested question list
Error message
Ask question index exceeded the requested question list
What it means
A defensive internal invariant in the multi-question loop: resultsByIndex is pre-sized to params.questions.length, so params.questions[questionIndex] should always exist while the loop condition holds. If the array somehow contains a hole (sparse array) or was mutated during iteration, this plain Error is thrown rather than dereferencing undefined.
Source
Thrown at packages/coding-agent/src/tools/ask.ts:1055
timedOut: timedOut || undefined,
};
const responseText = formatSingleQuestionResponse({
selectedOptions,
customInput,
note,
timedOut: timedOut || undefined,
multi: q.multi ?? false,
});
return { content: [{ type: "text" as const, text: responseText }], details };
}
const resultsByIndex: Array<QuestionResult | undefined> = Array.from({ length: params.questions.length });
let questionIndex = 0;
while (questionIndex < params.questions.length) {
const q = params.questions[questionIndex];
if (!q) throw new Error("Ask question index exceeded the requested question list");
const previous = resultsByIndex[questionIndex];
const navigation: NavigationControls = {
allowBack: questionIndex > 0,
allowForward: true,
progressText: `${questionIndex + 1}/${params.questions.length}`,
};
const {
optionLabels,
selectedOptions,
customInput,
note,
navigation: navAction,
cancelled,
timedOut,
} = await askQuestion(q, { previous, navigation });
if (cancelled && !timedOut) {
context.abort();View on GitHub (pinned to 9690622007)
Solutions
- Ensure the questions array is dense: contiguous indices 0..length-1 with a Question at each.
- Construct with literal/array methods (map, filter with type narrowing) instead of index assignment on an empty array.
- Filter out holes before calling: `questions.filter(Boolean)` then verify length matches expected.
Example fix
// before (sparse) const questions = []; questions[0] = q1; questions[2] = q3; // hole at index 1 // after const questions = [q1, q3]; // dense array
Defensive patterns
Strategy: validation
Validate before calling
function assertDenseQuestions(questions: Question[]): Question[] {
if (!Array.isArray(questions)) throw new TypeError('questions must be an array');
if (questions.filter(Boolean).length !== questions.length) {
throw new TypeError('questions contains holes/undefined entries');
}
return questions;
} Type guard
function hasNoHoles<T>(arr: T[]): boolean {
return arr.length === arr.filter(() => true).length && arr.every(x => x !== undefined && x !== null);
} Prevention
- Build questions arrays with literals or push/map, never index assignment into an empty array.
- Sanitize deserialized question lists (Object.values of a map → sort by key → dense array).
- Don't mutate the questions array while the tool is running.
When it happens
Trigger: Passing a sparse array as questions (e.g. `const qs = []; qs[2] = {...}`) or an array-like whose length exceeds actual elements; mutation of the questions array during the tool run.
Common situations: Programmatic/SDK callers building the questions array dynamically and leaving gaps; deserialization code that reconstructs a sparse array from a JSON map keyed by index.
Related errors
- No active model on agent
- Anthropic SDK request did not expose a stream response
- Anthropic cache refresh request did not expose a raw respons
- Cache benchmark prefix template is missing its raw prefix pl
- Sloppy edit completed without a result.
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/30ecb1b8124503ad.
Report an issue: GitHub.