{"record":{"id":"208af2d985acd68a","repo":"windmill-labs/windmill","slug":"draft-flow-path-has-no-value","errorCode":null,"errorMessage":"Draft flow \"${path}\" has no value.","messagePattern":"Draft flow \"(.+?)\" has no value\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/global/core.ts","lineNumber":5158,"sourceCode":"\treturn writeScriptDraft(\n\t\t{\n\t\t\tpath,\n\t\t\tsummary: base.summary,\n\t\t\tlanguage: base.language,\n\t\t\tcontent: updated\n\t\t},\n\t\tctx\n\t)\n}\n\nasync function loadFlowDraftValue(\n\tpath: string,\n\tworkspace: string\n): Promise<{ flow: FlowDraftValue; summary?: string }> {\n\tconst draft = await getGlobalDraft(workspace, 'flow', path)\n\tif (draft) {\n\t\tif (draft.value === undefined || typeof draft.value === 'string') {\n\t\t\tthrow new Error(`Draft flow \"${path}\" has no value.`)\n\t\t}\n\t\treturn { flow: draft.value as FlowDraftValue, summary: draft.summary }\n\t}\n\tconst flow = await FlowService.getFlowByPath({ workspace, path })\n\treturn {\n\t\tflow: { value: flow.value, schema: flow.schema, groups: flow.value.groups ?? null },\n\t\tsummary: flow.summary\n\t}\n}\n\n/**\n * `write_flow` accepts `inline_script.<id>` placeholders so the model can\n * overwrite a flow without re-sending (or even reading) unchanged rawscript\n * bodies. Resolve them against the current draft/deployed flow: an id with a\n * stored body keeps it, a new module's own-id placeholder becomes an empty body\n * (to fill via set_flow_module_code), and anything else rejects the write.\n */\nasync function resolveWriteFlowInlineScripts(","sourceCodeStart":5140,"sourceCodeEnd":5176,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/global/core.ts#L5140-L5176","documentation":"When reading a flow draft, the code expects the draft's value to be a structured FlowDraftValue object. If the draft exists but its value is undefined or only a string, it cannot produce a usable flow representation, so it throws. This keeps the model from treating a placeholder or serialized draft as a real flow value.","triggerScenarios":"getGlobalDraft(workspace, 'flow', path) returns a draft with `value === undefined` or a string value — e.g. a flow draft created without a value payload or with a stale string body.","commonSituations":"A write_flow call was interrupted after registering the draft but before writing the value; an older draft format stored the flow as a JSON string that the new reader no longer accepts; a flow draft was created for a path but value construction failed upstream.","solutions":["Delete the corrupted/empty flow draft and read again so it falls back to the deployed flow.","Re-run write_flow with a complete flow value to overwrite the draft.","Use patch_flow_json only after a valid draft or deployed flow exists."],"exampleFix":"// before\ndraftStore.set(workspace, 'flow', path, { value: JSON.stringify(flow) }) // string value rejected\n// after\ndraftStore.set(workspace, 'flow', path, { value: flowValue }) // structured FlowDraftValue","handlingStrategy":"type-guard","validationCode":"const draft = await getGlobalDraft(workspace, 'flow', path)\nif (draft && (draft.value === undefined || typeof draft.value === 'string')) {\n  await deleteGlobalDraft(workspace, 'flow', path) // fall back to deployed flow\n}","typeGuard":"function isFlowDraftValue(v: unknown): v is FlowDraftValue {\n  return !!v && typeof v === 'object' && !Array.isArray(v) && 'value' in (v as object)\n}","tryCatchPattern":"try {\n  const { flow } = await readFlow(path)\n} catch (e) {\n  if (String(e.message).includes('has no value')) {\n    await deleteDraft('flow', path)\n    const flow = await FlowService.getFlowByPath({ workspace, path })\n  } else throw e\n}","preventionTips":["Write flow drafts only with a complete structured value, never raw JSON strings.","After any interrupted write_flow run, verify or delete the draft.","Keep one draft format; migrate old string-valued drafts before reading."],"tags":["draft-state","flows","ai-tooling"],"backgroundTag":"incomplete-draft-state","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}