can1357/oh-my-pi · error
data is required when yield indicates success
Error message
data is required when yield indicates success
What it means
A yield that signals success without useLastTurn must include a `data` payload. If data is null (or absent) on a non-last-turn success, the tool throws because a successful result with no content cannot be assembled or validated. Error-status yields and useLastTurn yields bypass this check.
Source
Thrown at packages/coding-agent/src/tools/yield.ts:438
throw new Error(
`Section ${formatYieldLabels(yieldType as string[])} uses unknown incremental yield label(s): ${formatYieldLabels(unknownLabels)}. Resubmit with one of the schema's labels: ${validLabels}.`,
);
}
}
// A schema-bound terminal last-turn yield with no accumulated sections can
// only assemble raw prose, which finalization then rejects post-mortem as a
// fatal schema_violation the child can no longer correct. Catch it here as
// a retryable error instead. With sections present, a data-less finalize
// legitimately closes the incremental flow (assembly keeps the sections).
if (status === "success" && useLastTurn && !isIncremental && this.#validate && !this.#hasIncrementalSections) {
throw new Error(
"This task requires structured output matching the declared schema; a last-turn result cannot satisfy it. " +
`Submit the full object: {"result":{"data":<object matching the schema>}}.`,
);
}
if (status === "success" && !useLastTurn) {
if (data === null) {
throw new Error("data is required when yield indicates success");
}
const validateData = (value: unknown): JsonSchemaValidationResult | undefined =>
isIncremental
? this.#validateIncrementalSection(yieldType as string[], value)
: this.#validate
? this.#validate(value)
: undefined;
let sectionFailure = validateData(data);
if (sectionFailure && !sectionFailure.success && typeof data === "string") {
// Lossless recovery: a JSON-encoded payload string parses to exactly
// the intended value (executor finalization already parses terminal
// yields the same way). Never the reverse — stringifying objects to
// fit string-typed fields is silent corruption.
const parsed = parseJsonContainerString(data);
if (parsed !== undefined) {
const revalidated = validateData(parsed);
if (revalidated === undefined || revalidated.success) {
data = parsed;View on GitHub (pinned to 9690622007)
Solutions
- Resubmit with {result: {data: <your output>}}, matching the declared schema even if the content is empty (e.g. {items: []})
- If there is genuinely no result and the task failed, use {result: {error: "reason"}} instead
- If the answer lives in the final assistant message, use the useLastTurn variant rather than null data
- Fix the caller so falsy-but-valid values are not coerced to null
Example fix
// before
yield({ result: { data: null } });
// after
yield({ result: { data: { items: [], summary: "no findings" } } }); Defensive patterns
Strategy: validation
Validate before calling
if (status === 'success' && !useLastTurn && (data === null || data === undefined)) {
throw new TypeError('success yield requires a data payload');
} Type guard
function successHasData(r) {
return !(r.status === 'success' && r.useLastTurn !== true && (r.data === null || r.data === undefined));
} Try / catch
try {
yield({ result: { data } });
} catch (err) {
if (err.message === 'data is required when yield indicates success') {
yield({ result: { data: emptyButValidObject() } });
} else throw err;
} Prevention
- Never coerce results to null — preserve falsy-but-valid values (0, "", false)
- For 'nothing found', yield a schema-valid empty object (e.g. {items: []})
- Route genuine failures through {result:{error}} instead of null data
When it happens
Trigger: Calling yield with a success status, useLastTurn not set, and data explicitly null or omitted — e.g. {result: {data: null}} or {result: {status: "success"}}.
Common situations: A caller converts a falsy result (empty string, 0, false) into null before yielding; a template leaves the data field blank; an agent finishes with 'nothing to report' instead of yielding an empty-but-schema-valid object.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- result cannot contain both data and error
- result must contain either \`data\` or \`error\`. Use \`{res
- Section ${formatYieldLabels(yieldType as string[])} uses unk
- This task requires structured output matching the declared s
- ${scope} does not match schema: ${formatAllValidationIssues(
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/045991b66a1ee86a.
Report an issue: GitHub.