{"record":{"id":"884a32075516686d","repo":"different-ai/openwork","slug":"workflow-invalid-schema","errorCode":"workflow_invalid_schema","errorMessage":"workflow_invalid_schema:${parsed.message}","messagePattern":"workflow_invalid_schema:(.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-api/src/workflows.ts","lineNumber":647,"sourceCode":"    const resolved = manifestByPath.get(call.name)\n    if (!resolved) throw new Error(`workflow_capability_unavailable:${call.name}`)\n    if (resolved.readOnly !== true) throw new Error(`workflow_requires_read_only_capabilities:${call.name}`)\n    if (!requiredCapabilities.some((entry) => entry.scriptPath === resolved.scriptPath)) {\n      requiredCapabilities.push({\n        capabilityName: resolved.capabilityName,\n        scriptPath: resolved.scriptPath,\n      })\n    }\n  }\n  const normalizedPayloadJson = {\n    language: \"codemode-js\",\n    ...(input.workflow.inputSchema === undefined ? {} : { inputSchema: input.workflow.inputSchema }),\n    ...(input.workflow.outputSchema === undefined ? {} : { outputSchema: input.workflow.outputSchema }),\n    ...(input.workflow.currentInput === undefined ? {} : { exampleInput: input.workflow.currentInput }),\n    requiredCapabilities,\n  }\n  const parsed = parseCodemodeScriptPayload(normalizedPayloadJson)\n  if (!parsed.ok) throw new Error(`workflow_invalid_schema:${parsed.message}`)\n  if (parsed.payload.inputSchema) {\n    const validation = validateCodemodeScriptInput(parsed.payload.inputSchema, input.workflow.currentInput)\n    if (!validation.ok) throw new Error(\"workflow_current_input_invalid\")\n  }\n\n  return db.transaction(async (tx) => {\n    const plugins = requestedPluginId\n      ? await tx.select().from(PluginTable).where(and(\n          eq(PluginTable.id, requestedPluginId),\n          eq(PluginTable.organizationId, organizationId),\n          eq(PluginTable.status, \"active\"),\n          isNull(PluginTable.deletedAt),\n        )).limit(1).for(\"update\")\n      : await tx.select().from(PluginTable).where(and(\n          eq(PluginTable.organizationId, organizationId),\n          eq(PluginTable.createdByOrgMembershipId, ownerMemberId),\n          eq(PluginTable.name, DEFAULT_WORKFLOWS_PLUGIN_NAME),\n          eq(PluginTable.status, \"active\"),","sourceCodeStart":629,"sourceCodeEnd":665,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-api/src/workflows.ts#L629-L665","documentation":"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.","triggerScenarios":"Providing inputSchema or outputSchema that parseCodemodeScriptPayload rejects (not a valid JSON schema object, wrong shape/type), or a payload combination the parser deems invalid.","commonSituations":"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.","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"],"exampleFix":"// before\ninputSchema: JSON.stringify({ type: 'object', properties: { q: { type: 'string' } } })\n// after\ninputSchema: { type: 'object', properties: { q: { type: 'string' } }, required: ['q'] }","handlingStrategy":"validation","validationCode":"const payload = { language: 'codemode-js', inputSchema: myInputSchema, outputSchema: myOutputSchema, exampleInput: myInput }\nconst parsed = parseCodemodeScriptPayload(payload) // run the same parser client-side first\nif (!parsed.ok) throw new Error(`fix schema before saving: ${parsed.message}`)","typeGuard":"function isJsonObjectSchema(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v) && (v as { type?: unknown }).type === 'object'\n}","tryCatchPattern":"try {\n  await saveWorkflow(input)\n} catch (err) {\n  const m = /^workflow_invalid_schema:(.+)$/.exec(err instanceof Error ? err.message : '')\n  if (m) console.error(`Schema rejected: ${m[1]}`)\n}","preventionTips":["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"],"tags":["schema","validation","json-schema","workflows"],"backgroundTag":"schema-validation-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}