windmill-labs/windmill · error

This pipeline is read-only for your role; AI edits are disab

Error message

This pipeline is read-only for your role; AI edits are disabled.

What it means

The pipeline page's AI assistant calls ensureEditable() before proposing any node edit. If the current user is an operator (lacks edit permission on the pipeline), the page refuses AI edits outright with this error instead of silently entering edit mode where changes would be invisible or unactionable.

Source

Thrown at frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte:497

	// the flow/script editor applies AI edits), which the user then deploys. The
	// build/edit logic is shared verbatim with the in-session preview
	// (PipelineEditorView) via createPipelineAiHelpers.

	const pipelineAiHelpers = createPipelineAiHelpers({
		getFolder: () => folder,
		getWorkspace: () => $workspaceStore,
		getResolvedGraph: () => graphWithDraft,
		getDrafts: () => pe.drafts,
		setDrafts: (next) => (pe.drafts = next),
		newDraftLocalId: pe.newDraftLocalId,
		onForgetPath: (path) => forgetPath(path),
		onShowDrafts: () => (includeDrafts = true),
		onProposeNode: (path) => focusPipelineNode(`script:${path}`),
		ensureEditable: () => {
			// Auto-enter edit so AI changes are visible/actionable, unless the user
			// is an operator (no edit permission) — then refuse with a clear error.
			if (isOperator) {
				throw new Error('This pipeline is read-only for your role; AI edits are disabled.')
			}
			if (mode !== 'edit') setMode('edit')
		},
		onRunStarted: (jobId, path) => {
			activeRunnables.arm(`script:${path}`)
			runsPendingJobId = jobId
			runsRefreshKey++
			activeRunnable = { kind: 'script', path }
			activeRunnableJobId = jobId
		}
	})

	onMount(() => aiChatManager.setPipelineHelpers(pipelineAiHelpers))

	// Navigation guard state. `pendingNavigationUrl` holds the URL the user
	// tried to leave to so we can complete the navigation after they pick
	// "Save all" or "Discard all"; `bypassNavigationGuard` is the standard
	// SvelteKit pattern for "this navigation was already approved, don't

View on GitHub (pinned to e474e8803c)

Solutions

  1. Ask an editor/admin to make the change, or request edit permission on the pipeline/folder
  2. Operate under an account with write access to the pipeline
  3. Read-only users can still view runs and drafts (onShowDrafts) but not propose edits
Defensive patterns

Strategy: try-catch

Validate before calling

const canEdit = workspaceStore.perms.editable !== false && !isOperator;
if (!canEdit) throw new Error('Read-only role: AI edits disabled');

Type guard

function canProposeEdits(user: {isOperator: boolean}): boolean {
  return !user.isOperator;
}

Try / catch

try { assistant.ensureEditable(); } catch (e) {
  if (e.message.includes('read-only')) { notify('Request edit access to use AI edits'); }
  else throw e;
}

Prevention

When it happens

Trigger: An operator-role user asks the AI to modify the pipeline while in view/ops mode; ensureEditable() checks isOperator and throws before setMode('edit').

Common situations: Shared workspaces where operators run pipelines but cannot edit; user forgot their role is read-only; attempting AI-generated drafts on a pipeline they can only operate.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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