windmill-labs/windmill · error

No unsaved draft at '${path}' to discard.

Error message

No unsaved draft at '${path}' to discard.

What it means

Thrown by removeProposedNode in createPipelineAiHelpers when asked to discard a draft at `path` that is not present in the current drafts map. The pipeline AI proposes asset-pipeline nodes as unsaved drafts; this fires when the tool targets a path that was never proposed or was already discarded — it is a sentinel guard, not an unexpected failure.

Source

Thrown at frontend/src/lib/components/assets/AssetGraph/pipelineAiHelpers.ts:343

				localId: existing?.localId ?? deps.newDraftLocalId(),
				script: { ...baseScript, content },
				outputAssets,
				inputAssets: inferred.reads
			})
			deps.setDrafts(next)
			deps.onShowDrafts?.()
			deps.onProposeNode?.(path)
			// Deployable lineage only (see proposeNode): body writes + materialize target.
			return {
				detectedReads: inferred.reads.map(assetUri),
				detectedWrites: dedupeAssets([...inferred.writes, ...materializeWrites(content)]).map(
					assetUri
				)
			}
		},
		removeProposedNode: async (path) => {
			if (!deps.getDrafts().has(path)) {
				throw new Error(`No unsaved draft at '${path}' to discard.`)
			}
			const next = new Map(deps.getDrafts())
			next.delete(path)
			deps.setDrafts(next)
			deps.onForgetPath?.(path)
		},
		testNode: async (path, args) => {
			const workspace = deps.getWorkspace()
			if (!workspace) return undefined
			const draft = deps.getDrafts().get(path)
			try {
				let jobId: string
				if (draft) {
					// Un-deployed/edited body: preview-run the draft content so it can be
					// tested before deploying.
					jobId = await JobService.runScriptPreview({
						workspace,
						requestBody: {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Check `path` against the currently proposed/open drafts before calling removeProposedNode
  2. Refresh the drafts list to confirm the draft still exists and use its exact path
  3. If the draft was already discarded, treat the operation as already done instead of retrying
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at frontend/src/lib/components/assets/AssetGraph/pipelineAiHelpers.ts:343 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/997ead4481376fde. Report an issue: GitHub.