windmill-labs/windmill · error

Could not diff ${type} "${path}": ${entry.errorMessage}

Error message

Could not diff ${type} "${path}": ${entry.errorMessage}

What it means

Windmill's AI copilot `diff` tool computes a draft-vs-deployed diff for an item. Before diffing, it reads a precomputed workspace diff entry; when that entry reports status 'error', the tool surfaces the underlying diff-engine failure verbatim via this thrown Error. It is a wrapper around a server-side/overlay diff computation failure, not a usage mistake by the caller.

Source

Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:6597

				after: afterSide,
				valueUncomparable
			} = maskVariableDiffSides(beforeSide, afterSide))
			flushCaveat += valueUncomparable ? SECRET_UNCOMPARABLE_NOTE : VARIABLE_MASKED_NOTE
		}
		const parts = computeDiffParts(beforeSide, afterSide, 'deployed', 'draft')
		patch = parts.patch
		files = parts.files
		flushCaveat +=
			'Note: this diff includes unsaved editor changes that are NOT saved to the server draft yet (auto-save is off or the last save failed).\n\n'
	} else if (flushSkipped) {
		throw new Error(
			`The latest editor changes for ${type} "${path}" could not be saved and are not readable; retry once the editor saves.`
		)
	} else {
		const entry = await readWorkspaceDiffEntry(workspace, itemKind, storagePath)
		if (entry) {
			if (entry.status === 'error') {
				throw new Error(`Could not diff ${type} "${path}": ${entry.errorMessage}`)
			}
			patch = entry.patch ?? ''
			noDeployed = entry.noDeployed === true
			files = entry.files
			valueUncomparable = entry.valueUncomparable === true
			if (entry.valueMasked) {
				flushCaveat += valueUncomparable ? SECRET_UNCOMPARABLE_NOTE : VARIABLE_MASKED_NOTE
			}
		} else {
			// Not in the draft listing — either no draft at all (deployed is current),
			// nothing at the path, or a listing/overlay disagreement; ask the overlay.
			let values: Awaited<ReturnType<typeof getDraftDiffValues>>
			try {
				values = await getDraftDiffValues(itemKind, storagePath, workspace)
			} catch (e) {
				if ((e as { status?: number } | null | undefined)?.status === 404) {
					throw new Error(
						`No ${type} found at "${path}" — it has neither a deployed version nor a draft.`

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read entry.errorMessage in the message for the root cause and address that underlying failure (fix the malformed draft content or redeploy the item)
  2. Retry the diff after the underlying item is fixed; the entry status is recomputed
  3. If the item is broken beyond repair, delete the draft or redeploy the deployed version so a fresh diff can be computed
  4. Report a bug with the item kind/path and errorMessage if it reproduces on healthy items

Example fix

// before: calling diff on an item with a broken draft
await diff({ type: 'script', path: 'f/broken_script' })
// after: fix or clear the broken draft first, or diff after redeploying
await deployDraft({ path: 'f/broken_script' })
await diff({ type: 'script', path: 'f/broken_script' })
Defensive patterns

Strategy: try-catch

Validate before calling

const entry = await readWorkspaceDiffEntry(workspace, itemKind, storagePath)
if (entry?.status === 'error') {
  console.warn(`Diff for ${type} "${path}" is in error state: ${entry.errorMessage}`)
}

Type guard

function isDiffErrorEntry(entry: { status: string; errorMessage?: string } | null): entry is { status: 'error'; errorMessage: string } {
  return entry !== null && entry.status === 'error'
}

Try / catch

try {
  return await diffItem({ type, path })
} catch (e) {
  if (String(e?.message).startsWith('Could not diff')) {
    // underlying diff-engine failure: fix/redploy the item, then retry
    return retryAfterFix()
  }
  throw e
}

Prevention

When it happens

Trigger: Calling the copilot diff tool for a type/path whose workspace diff entry was computed with status='error'; the workspace diff overlay failed to compute the diff for that item (e.g. malformed stored content, diff computation exception), and `readWorkspaceDiffEntry` returns that error status.

Common situations: Corrupt or incompatible stored draft content for the item; an internal diff-engine failure for an unusual item kind; stale overlay cache after failed deploys; items whose deployed and draft sides cannot be serialized for diffing.

Related errors


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