can1357/oh-my-pi · error
type must be a string or non-empty array of strings
Error message
type must be a string or non-empty array of strings
What it means
The yield tool's optional `type` parameter classifies the result (string or non-empty array of strings). parseYieldType accepts undefined/null (treated as untyped) and valid shapes, and throws a plain Error for anything else — e.g. numbers, empty arrays, or arrays containing non-strings. Note strict-mode providers can deliver `type: null`, which is deliberately tolerated.
Source
Thrown at packages/coding-agent/src/tools/yield.ts:103
items: { type: "string" },
},
],
description: "Optional result type. A non-empty string array is incremental; a string is terminal.",
};
function isYieldType(value: unknown): value is string | string[] {
return (
typeof value === "string" ||
(Array.isArray(value) && value.length > 0 && value.every(item => typeof item === "string"))
);
}
function parseYieldType(value: unknown): string | string[] | undefined {
// Strict-mode providers (OpenAI/Codex) make the optional `type` property
// required+nullable, so an untyped final yield arrives as `type: null`.
if (value === undefined || value === null) return undefined;
if (isYieldType(value)) return value;
throw new Error("type must be a string or non-empty array of strings");
}
/** Parse a `{`/`[`-leading JSON string; undefined on non-container or parse failure. */
function parseJsonContainerString(value: string): unknown {
const trimmed = value.trim();
if (!(trimmed.startsWith("{") || trimmed.startsWith("["))) return undefined;
try {
return JSON.parse(trimmed);
} catch {
return undefined;
}
}
function isPlainRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}
/**
* Resolve the `result` record from raw yield arguments, losslessly salvagingView on GitHub (pinned to 9690622007)
Solutions
- Omit `type` entirely (or send null) when there is no classification.
- Send a single string, e.g. "finding".
- Send a non-empty array of strings for multiple classifications, e.g. ["security","high"].
- Ensure all array elements are strings — convert enums/numbers to strings before passing.
Example fix
// before
yield({ result: { data: x }, type: [] })
// after
yield({ result: { data: x }, type: "finding" }) Defensive patterns
Strategy: type-guard
Validate before calling
const t = (p: { type?: unknown }).type; if (t !== undefined && t !== null && typeof t !== "string" && !(Array.isArray(t) && t.length > 0 && t.every((s) => typeof s === "string"))) throw new Error("type must be a string or non-empty array of strings"); Type guard
function isYieldType(v: unknown): v is string | string[] { return typeof v === "string" || (Array.isArray(v) && v.length > 0 && v.every((s) => typeof s === "string")); } Try / catch
try { yield(params); } catch (e) { if (e.message === "type must be a string or non-empty array of strings") { delete params.type; return yield(params); } throw e; } Prevention
- Only pass strings or non-empty string arrays as `type`.
- Omit `type` when there is no classification (null is tolerated).
- Stringify enum values before assigning to `type`.
- Add a schema/constraint on `type` in generated prompts.
When it happens
Trigger: Passing `type: 42`, `type: true`, `type: {}`, `type: []` (empty array), or `type: [1,2]` in the yield tool parameters.
Common situations: A model emits a numeric type code or an empty array when it has no classification; prompt/schema drift causes the model to fill `type` with an invalid literal.
Related errors
- symbol is required for project-aware ${action}; pass symbol=
- Symbol "${symbol}" occurrence ${occurrence} is out of bounds
- Report cannot be empty.
- Limit must be a positive number
- scoped_path security scans require at least one include path
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/2326a11c1f0038b0.
Report an issue: GitHub.