different-ai/openwork · error
workflow_invalid_schema
workflow_invalid_schema
Error message
workflow_invalid_schema:${parsed.message} What it means
Before persisting, saveWorkflow assembles a normalized payload (language, optional inputSchema/outputSchema, exampleInput from currentInput, requiredCapabilities) and validates it with parseCodemodeScriptPayload. If the payload fails parsing/schema validation, the error 'workflow_invalid_schema:<message>' is thrown with the underlying parser message appended. The root cause detail is in the thrown message after the colon.
Source
Thrown at ee/apps/den-api/src/workflows.ts:647
const resolved = manifestByPath.get(call.name)
if (!resolved) throw new Error(`workflow_capability_unavailable:${call.name}`)
if (resolved.readOnly !== true) throw new Error(`workflow_requires_read_only_capabilities:${call.name}`)
if (!requiredCapabilities.some((entry) => entry.scriptPath === resolved.scriptPath)) {
requiredCapabilities.push({
capabilityName: resolved.capabilityName,
scriptPath: resolved.scriptPath,
})
}
}
const normalizedPayloadJson = {
language: "codemode-js",
...(input.workflow.inputSchema === undefined ? {} : { inputSchema: input.workflow.inputSchema }),
...(input.workflow.outputSchema === undefined ? {} : { outputSchema: input.workflow.outputSchema }),
...(input.workflow.currentInput === undefined ? {} : { exampleInput: input.workflow.currentInput }),
requiredCapabilities,
}
const parsed = parseCodemodeScriptPayload(normalizedPayloadJson)
if (!parsed.ok) throw new Error(`workflow_invalid_schema:${parsed.message}`)
if (parsed.payload.inputSchema) {
const validation = validateCodemodeScriptInput(parsed.payload.inputSchema, input.workflow.currentInput)
if (!validation.ok) throw new Error("workflow_current_input_invalid")
}
return db.transaction(async (tx) => {
const plugins = requestedPluginId
? await tx.select().from(PluginTable).where(and(
eq(PluginTable.id, requestedPluginId),
eq(PluginTable.organizationId, organizationId),
eq(PluginTable.status, "active"),
isNull(PluginTable.deletedAt),
)).limit(1).for("update")
: await tx.select().from(PluginTable).where(and(
eq(PluginTable.organizationId, organizationId),
eq(PluginTable.createdByOrgMembershipId, ownerMemberId),
eq(PluginTable.name, DEFAULT_WORKFLOWS_PLUGIN_NAME),
eq(PluginTable.status, "active"),View on GitHub (pinned to 2b7df46e8a)
Solutions
- Read the parser detail in the error message after 'workflow_invalid_schema:' and fix the schema accordingly
- Pass inputSchema/outputSchema as plain JSON Schema objects, not strings
- Validate the schema locally with the same JSON Schema validator the parser uses before calling saveWorkflow
- Remove the optional schema fields to confirm the rest of the payload parses, then add them back incrementally
Example fix
// before
inputSchema: JSON.stringify({ type: 'object', properties: { q: { type: 'string' } } })
// after
inputSchema: { type: 'object', properties: { q: { type: 'string' } }, required: ['q'] } Defensive patterns
Strategy: validation
Validate before calling
const payload = { language: 'codemode-js', inputSchema: myInputSchema, outputSchema: myOutputSchema, exampleInput: myInput }
const parsed = parseCodemodeScriptPayload(payload) // run the same parser client-side first
if (!parsed.ok) throw new Error(`fix schema before saving: ${parsed.message}`) Type guard
function isJsonObjectSchema(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v) && (v as { type?: unknown }).type === 'object'
} Try / catch
try {
await saveWorkflow(input)
} catch (err) {
const m = /^workflow_invalid_schema:(.+)$/.exec(err instanceof Error ? err.message : '')
if (m) console.error(`Schema rejected: ${m[1]}`)
} Prevention
- Parse schemas with parseCodemodeScriptPayload locally before saving
- Pass schemas as objects, never pre-serialized JSON strings
- Keep schemas to standard JSON Schema keywords the parser supports
- Add unit tests for schema round-tripping in your workflow builder UI
When it happens
Trigger: Providing inputSchema or outputSchema that parseCodemodeScriptPayload rejects (not a valid JSON schema object, wrong shape/type), or a payload combination the parser deems invalid.
Common situations: Hand-written JSON Schema with typos or non-standard keywords; passing a schema as a JSON string instead of an object; schemas built by another tool that emit unsupported constructs; currentInput type mismatching the declared schema shape in ways the parser flags.
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
- Invalid cloud provider sync response.
- Invalid cloud provider sync status response.
- invalid_cloud_plugin
- Environment variable store has an invalid format
- workflow_current_input_invalid
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/884a32075516686d.
Report an issue: GitHub.