jamiepine/voicebox · warning · HTTPException
Each example must be a [user, assistant] pair
Error message
Each example must be a [user, assistant] pair
What it means
Returned by POST /llm/generate when request.examples contains an inner list whose length is not exactly 2. examples is typed Optional[List[List[str]]] with max_length=8; the schema guarantees a list-of-lists-of-strings but cannot enforce the inner arity, so this route-level check enforces the [user, assistant] pair contract before the pairs are zipped into chat turns.
Source
Thrown at backend/routes/llm.py:60
task_manager.error_download(progress_model_name, str(e))
task_manager.start_download(progress_model_name)
create_background_task(download_llm_background())
return JSONResponse(
status_code=202,
content={
"message": f"Qwen3 {model_size} is being downloaded. Please wait and try again.",
"model_name": progress_model_name,
"downloading": True,
},
)
examples: list[tuple[str, str]] | None = None
if request.examples:
for pair in request.examples:
if len(pair) != 2:
raise HTTPException(
status_code=400,
detail="Each example must be a [user, assistant] pair",
)
examples = [(pair[0], pair[1]) for pair in request.examples]
try:
text = await backend.generate(
prompt=request.prompt,
system=request.system,
max_tokens=request.max_tokens,
temperature=request.temperature,
model_size=model_size,
examples=examples,
)
return models.LLMGenerateResponse(text=text, model_size=model_size)
except Exception as e:
# The backend exception text can include filesystem paths and stack
# frames — log it server-side and hand the client a generic message.View on GitHub (pinned to 51f49dea19)
Solutions
- Ensure every entry in examples is exactly [userText, assistantText] — two non-empty strings.
- Validate the shape on the client before sending: pairs.every(p => Array.isArray(p) && p.length === 2).
- If you need richer few-shot metadata (labels, tags), keep it out of examples — those pairs map directly onto chat messages.
- Reduce examples to <=8 pairs to also satisfy the max_length constraint on the field.
Example fix
// before
body: {prompt, examples: [['q','a','why']]}
// after
body: {prompt, examples: [['q','a']]} Defensive patterns
Strategy: validation
Validate before calling
function validateExamples(ex?: string[][]) {
if (!ex) return undefined;
if (ex.length > 8) throw new Error('At most 8 example pairs');
for (const p of ex) {
if (!Array.isArray(p) || p.length !== 2 || typeof p[0] !== 'string' || typeof p[1] !== 'string') {
throw new Error('Each example must be a [user, assistant] pair');
}
}
return ex as [string, string][];
} Type guard
type ChatPair = [string, string];
function isChatPair(p: unknown): p is ChatPair {
return Array.isArray(p) && p.length === 2 && p.every(v => typeof v === 'string');
}
const isExamples = (x: unknown): x is ChatPair[] =>
Array.isArray(x) && x.length <= 8 && x.every(isChatPair); Try / catch
if (payload.examples && !isExamples(payload.examples)) {
// surface inline error in the UI; do not send
} else {
await fetch('/llm/generate', {method:'POST', body: JSON.stringify(payload)});
} Prevention
- Construct examples from typed [user, assistant] tuples in the client, never from free-form arrays.
- Cap at 8 pairs client-side to satisfy both the max_length field constraint and the pair-shape rule.
- Unit-test the few-shot builder to guarantee arity before serializing.
When it happens
Trigger: POST /llm/generate with examples like [["u1","a1","extra"]] (3 elements), [["only-user"]] (1 element), or [[]] (0 elements). A single malformed pair aborts the whole request before generation.
Common situations: Refinement service assembled a triple by mistake (user, assistant, rationale); client serialized a single string instead of a pair; prompt template builder emitted an empty placeholder pair; JSON edit left a dangling comma producing a 3-element array.
Related errors
- Invalid LLM size '{model_size}'. Must be one of: {sorted(val
- Model ${model_size} is not downloaded yet. Use /generate to
- Model {model_size} is not downloaded yet. Use /generate to t
- {display} model is not downloaded yet. Use /generate to trig
- Unknown LLM engine: {engine}. Supported: {list(LLM_ENGINES.k
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/e1d74fef3b5bb738.
Report an issue: GitHub.