windmill-labs/windmill · warning · Error

Not found

Error message

Not found

What it means

The SSE watcher for a test/preview job treats a 'not_found' event from the server as fatal: it closes the EventSource and throws Error('Not found'). This means the job id being streamed does not exist (anymore) on the backend.

Source

Thrown at frontend/src/lib/components/JobLoader.svelte:834

							let type = previewJobUpdates.type
							if (type == 'timeout') {
								currentEventSource?.close()
								currentEventSource = undefined
								loadTestJobWithSSE(id, 0, callbacks)
								return
							} else if (type == 'ping') {
								setNoPingTimeout(id, attempt, callbacks)
								return
							} else if (type == 'error') {
								currentEventSource?.close()
								currentEventSource = undefined
								console.error('SSE error:', previewJobUpdates)
								throw new Error('SSE error: ' + previewJobUpdates)
							} else if (type == 'not_found') {
								currentEventSource?.close()
								currentEventSource = undefined
								console.error('Not found')
								throw new Error('Not found')
							}
							jobUpdateLastFetch = new Date()

							if (job) {
								updateJobFromProgress(previewJobUpdates, job, callbacks)
							} else if (onlyResult && callbacks?.running && previewJobUpdates.running) {
								callbacks?.running?.({ id })
							}

							if (onlyResult && previewJobUpdates.new_result_stream) {
								resultOnlyResultStream = resultOnlyResultStream.concat(
									previewJobUpdates.new_result_stream
								)
								// console.log('resultOnlyResultStream', resultOnlyResultStream)
								callbacks?.resultStreamUpdate?.({
									id,
									result_stream: resultOnlyResultStream
								})

View on GitHub (pinned to e474e8803c)

Solutions

  1. Re-run the test/preview to generate a fresh job id, then watch the new stream
  2. Verify the job id still exists in the runs/history view
  3. Confirm you are in the same workspace as the job
  4. Disable onlyResult/watch on stale jobs before switching context

Example fix

// before
throw new Error('Not found')
// after
if (callbacks?.onNotFound) { callbacks.onNotFound(); return }
throw new Error('Not found')
Defensive patterns

Strategy: retry

Validate before calling

// confirm the job exists before watching
const exists = await fetch(`/api/w/${workspace}/jobs/${id}`).then(r => r.ok)

Try / catch

try {
  await loadTestJobWithSSE(id, callbacks)
} catch (e) {
  if (e.message === 'Not found') {
    // stale job id — re-run the test to obtain a fresh id, then re-watch
    await rerunAndWatch()
  } else throw e
}

Prevention

When it happens

Trigger: loadTestJobWithSSE subscribes to a job id the backend reports as not_found — the test job was purged, the run was deleted, or the id is stale/from another workspace.

Common situations: Watching a preview whose job already completed and was cleaned up; keeping a stale EventSource after re-deploying and regenerating the preview job; workspace switching without reloading the job id.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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