windmill-labs/windmill · warning · Error
Missing context for draft fetch
Error message
Missing context for draft fetch
What it means
In frontend/src/lib/components/DraftBadge.svelte:149, fetchDraft() requires workspace, itemKind, and path to call DraftService.getDraftForUser; if any is missing it throws "Missing context for draft fetch". This guards against querying drafts for an item that is not (yet) identified.
Source
Thrown at frontend/src/lib/components/DraftBadge.svelte:149
)
let busyFor = $state<string | null>(null)
let diffDrawer: DiffDrawer | undefined = $state(undefined)
let migrateOpen = $state(false)
// The hover popover sits above the diff drawer / migrate modal (z-index), so
// close it before opening either or it would cover them.
let popoverOpen = $state(false)
// Legacy (no-owner) drafts can only be resolved by workspace admins / superadmins.
const canMigrateLegacy = $derived(!!$userStore?.is_admin || !!$userStore?.is_super_admin)
function ownerKey(owner: DraftUser): string {
return owner.username ?? '__legacy__'
}
async function fetchDraft(owner: DraftUser): Promise<unknown> {
if (!workspace || !itemKind || !path) {
throw new Error('Missing context for draft fetch')
}
return (
await DraftService.getDraftForUser({
workspace,
kind: itemKind,
path,
username: owner.username ?? undefined
})
).value
}
async function viewDiff(owner: DraftUser) {
if (!workspace || !itemKind || !path) return
busyFor = ownerKey(owner)
try {
const [draftValue, deployed] = await Promise.all([
fetchDraft(owner),
fetchDeployedValueForDiff(workspace, itemKind, path)View on GitHub (pinned to e474e8803c)
Solutions
- Save the item first so it has a path before draft lookups
- Ensure the component is only rendered when workspace and path are set (use {#key path} or a guard)
- Check where itemKind/path are sourced and fix the empty value
Example fix
// before
{#if showDraft}<DraftBadge ... />{/if}
// after
{#if showDraft && path}<DraftBadge ... />{/if} Defensive patterns
Strategy: type-guard
Validate before calling
if (!workspace || !itemKind || !path) return; // skip draft fetch until item is identified
Type guard
function canFetchDraft(ctx: { workspace?: string; itemKind?: string; path?: string }): ctx is { workspace: string; itemKind: string; path: string } {
return Boolean(ctx.workspace && ctx.itemKind && ctx.path);
} Try / catch
try {
draft = await fetchDraft(owner);
} catch {
draft = undefined; // no draft yet or missing context — treat as no draft
} Prevention
- Render DraftBadge only when the item has a saved path
- Gate draft fetches behind a reactive check of workspace/itemKind/path
- Key the component with {#key path} so state resets when the path changes
When it happens
Trigger: DraftBadge rendered for an unsaved/new item with no path, or outside a workspace context — e.g. the component mounts before the item's path is assigned.
Common situations: Creating a brand-new script/flow and opening the draft badge before first save; component rendered in a context without workspace selection; a race where path prop is briefly empty on mount.
Related errors
- No flow available to test step from. Please ensure you have
- No pipeline editor is open. Pipeline tools only work on a /p
- No script code available to edit. Please ensure you have a s
- No model selected
- No workspace available
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/d8801e8e4567f905.
Report an issue: GitHub.