different-ai/openwork · error
workflow_snapshot_not_found
workflow_snapshot_not_found
Error message
workflow_snapshot_not_found
What it means
Thrown in deleteWorkflowSnapshotContent when no WorkflowRun row matches the given receiptId scoped to the config object's organization and id with a non-null config_object_version_id. The caller asked to delete (redact) a snapshot's content, but no corresponding workflow snapshot exists.
Source
Thrown at ee/apps/den-api/src/workflows.ts:472
})
return getWorkflowDetail({ context: input.context, configObjectId: resource.configObject.id })
}
export async function deleteWorkflowSnapshotContent(input: {
context: PluginArchActorContext
configObjectId: string
receiptId: string
}) {
const resource = await workflowResource(input.context, input.configObjectId, "manager")
const receiptId = parseReceiptId(input.receiptId)
const rows = await db.select().from(WorkflowRunTable).where(and(
eq(WorkflowRunTable.id, receiptId),
eq(WorkflowRunTable.organization_id, resource.configObject.organizationId),
eq(WorkflowRunTable.config_object_id, resource.configObject.id),
isNotNull(WorkflowRunTable.config_object_version_id),
)).limit(1)
const receipt = rows[0]
if (!receipt) throw new Error("workflow_snapshot_not_found")
if (!receipt.artifact_content_deleted_at) {
await db.update(WorkflowRunTable).set({
script_input: null,
validated_result: null,
result_markdown: null,
artifact_content_deleted_at: new Date(),
}).where(eq(WorkflowRunTable.id, receipt.id))
}
if (receipt.automation_run_id) {
const automationRuns = await db.select({ automationId: AutomationRunTable.automation_id })
.from(AutomationRunTable)
.where(eq(AutomationRunTable.id, receipt.automation_run_id)).limit(1)
const automationId = automationRuns[0]?.automationId
if (automationId) {
const retained = await db.select({ receipt: WorkflowRunTable, run: AutomationRunTable })
.from(WorkflowRunTable)
.innerJoin(AutomationRunTable, eq(AutomationRunTable.id, WorkflowRunTable.automation_run_id))View on GitHub (pinned to 2b7df46e8a)
Solutions
- Verify the receiptId belongs to the same organization and config object as the route's resource.
- Check the row is a test-run snapshot (config_object_version_id IS NOT NULL) before calling deletion.
- Treat the error as not-found: skip or log instead of retrying with the same id.
Example fix
// before await deleteWorkflowSnapshot(receiptId) // any id // after const [run] = await db.select().from(WorkflowRunTable) .where(and(eq(WorkflowRunTable.id, receiptId), isNotNull(WorkflowRunTable.config_object_version_id))) if (run) await deleteWorkflowSnapshot(receiptId)
Defensive patterns
Strategy: try-catch
Validate before calling
const [run] = await db.select({ id: WorkflowRunTable.id }).from(WorkflowRunTable)
.where(and(eq(WorkflowRunTable.id, receiptId),
eq(WorkflowRunTable.organization_id, orgId),
eq(WorkflowRunTable.config_object_id, configObjectId),
isNotNull(WorkflowRunTable.config_object_version_id))).limit(1)
const exists = !!run Try / catch
try {
await deleteWorkflowSnapshot(receiptId)
} catch (e) {
if (e.message === "workflow_snapshot_not_found") {
// already gone or wrong id: log and continue
} else throw e
} Prevention
- Confirm receiptId scope (org + config object) before calling.
- Only target runs with a non-null config_object_version_id.
- Make cleanup scripts tolerant of missing snapshots.
When it happens
Trigger: Calling the snapshot deletion route with a receiptId that does not exist, belongs to another org/config object, or whose row has a NULL config_object_version_id (i.e. not a version-producing test run); also firing the request twice after the first deletion partially succeeded — actually deletion is idempotent once found, so repeats mainly fail on wrong ids.
Common situations: Already-deleted or pruned workflow runs; typos or stale ids in cleanup scripts; passing an id from a different organization after an org switch in the client.
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
- workflow_test_receipt_already_used
- workflow_capability_unavailable
- workflow_requires_read_only_capabilities
- workflow_test_capability_mismatch
- automation_saved_script_version_not_found
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/1c96865d9859398e.
Report an issue: GitHub.