linshenkx/prompt-optimizer · error · EvaluationValidationError
${label} id must not be empty.
Error message
${label} id must not be empty. What it means
Every test case in an evaluation must have a non-empty id so results can be correlated back to inputs. validateTestCase throws when testCase.id is missing or whitespace — the message includes the label passed by the caller (e.g. 'Test case #3') to identify the offending case.
Source
Thrown at packages/core/src/services/evaluation/service.ts:1714
if (!block) {
throw new EvaluationValidationError(`${label} must not be empty.`);
}
if (!block.label?.trim()) {
throw new EvaluationValidationError(`${label} label must not be empty.`);
}
const hasContent = !!block.content?.trim();
const hasMedia = this.hasBlockMedia(block);
if (!hasContent && !hasMedia) {
throw new EvaluationValidationError(`${label} content must not be empty.`);
}
if (block.media) {
this.validateMediaItems(block.media, `${label} media`);
}
}
private validateTestCase(testCase: EvaluationTestCase | undefined, label: string): void {
if (!testCase?.id?.trim()) {
throw new EvaluationValidationError(`${label} id must not be empty.`);
}
this.validateContentBlock(testCase.input, `${label} input`);
}
private validateSnapshot(snapshot: EvaluationSnapshot | undefined, label: string): void {
if (!snapshot?.id?.trim()) {
throw new EvaluationValidationError(`${label} id must not be empty.`);
}
if (!snapshot?.label?.trim()) {
throw new EvaluationValidationError(`${label} label must not be empty.`);
}
if (!snapshot?.testCaseId?.trim()) {
throw new EvaluationValidationError(`${label} testCaseId must not be empty.`);
}
if (!snapshot?.promptText?.trim()) {
throw new EvaluationValidationError(`${label} promptText must not be empty.`);
}
if (!snapshot?.output?.trim()) {View on GitHub (pinned to 3e677b1d9f)
Solutions
- Assign a unique non-empty string id to every test case before submission
- Use the error message's label to find the exact entry and fix it
- Generate ids deterministically (e.g. slug or uuid) during import if the source lacks them
Example fix
// before
testCases: [{ input: { label: 'p', content: 'hi' } }]
// after
testCases: [{ id: 'tc-001', input: { label: 'p', content: 'hi' } }] Defensive patterns
Strategy: validation
Validate before calling
import { randomUUID } from 'node:crypto';
function ensureTestCaseIds(testCases: { id?: string }[]): void {
testCases.forEach((tc, i) => {
if (!tc.id?.trim()) tc.id = `tc-${i + 1}-${randomUUID().slice(0, 8)}`;
});
} Type guard
const hasTestCaseId = (tc: { id?: string } | undefined): boolean => !!tc?.id?.trim(); Try / catch
try {
await evaluationService.create(request);
} catch (err) {
if (err instanceof EvaluationValidationError && /id must not be empty/.test(err.message)) {
assignIdsAndRetry();
} else throw err;
} Prevention
- Always mint ids (uuid/slug) when building test cases
- Validate imported rows for a non-blank id column
- Type test case id as required string
When it happens
Trigger: Submitting an evaluation whose testCases array contains an entry with no id, an empty id, or an id of spaces. Typically from generated or imported test case lists.
Common situations: CSV/JSON import where the id column is blank; array index used as id but off-by-one left it undefined; deduplication code deleting ids; id field renamed during a schema migration.
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
- Result evaluation snapshot testCaseId must match testCase.id
- Compare evaluation requires at least one test case.
- Image result evaluation requires at least one output image e
- Compare evaluation requires at least two snapshots.
- Compare test case #${index + 1} id must be unique.
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/5a74d6e1f602f9d3.
Report an issue: GitHub.