windmill-labs/windmill · error · Error

Runnable "${target.key}" is not inline. Use read_workspace_i

Error message

Runnable "${target.key}" is not inline. Use read_workspace_item on the referenced ${runnable.runType ?? 'item'} instead.

What it means

The AI chat backend tool resolver only accepts runnables stored inline in the app draft (type 'inline' or 'runnableByName'). When a runnable references a shared workspace item (script, flow, etc.), editing it in place is not allowed; the model must fetch and read it via the read_workspace_item tool. This guard prevents accidentally overwriting shared workspace resources through the app draft.

Source

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

	return runnable?.inlineScript?.language === 'python3' ? 'py' : 'ts'
}

/**
 * Resolve a backend file target to its inline script body, validating that the
 * runnable exists, is inline, and matches the requested file extension. Throws
 * with a clear message otherwise.
 */
function getInlineRunnableContent(
	value: AppDraftValue,
	target: { kind: 'backend'; filePath: string; key: string; extension: 'ts' | 'py' },
	appPath: string
): { content: string; runnable: PersistedRunnable } {
	const runnable = value.runnables[target.key] as PersistedRunnable | undefined
	if (!runnable) {
		throw new Error(`Backend runnable "${target.key}" not found in app "${appPath}".`)
	}
	if (runnable.type !== 'inline' && runnable.type !== 'runnableByName') {
		throw new Error(
			`Runnable "${target.key}" is not inline. Use read_workspace_item on the referenced ${runnable.runType ?? 'item'} instead.`
		)
	}
	const expected = getInlineScriptExtension(runnable)
	if (target.extension !== expected) {
		throw new Error(
			`Runnable "${target.key}" language is ${expected}. Use backend/${target.key}/main.${expected}.`
		)
	}
	return { content: runnable.inlineScript?.content ?? '', runnable }
}

async function loadAppValueForRead(path: string, workspace: string): Promise<AppDraftValue> {
	const draft = await getGlobalDraft(workspace, 'app', path)
	if (draft && draft.value && typeof draft.value === 'object' && 'files' in draft.value) {
		return draft.value as AppDraftValue
	}

View on GitHub (pinned to e474e8803c)

Solutions

  1. Inspect value.runnables[target.key] to see the referenced runType and path
  2. Call read_workspace_item with the referenced item path to fetch its content
  3. Edit the referenced workspace item through its own workspace tool, not through the app draft
  4. Or change the app so the runnable is inline (type 'inline') if in-app editing is intended
Defensive patterns

Strategy: validation

Validate before calling

if (runnable.type !== 'inline' && runnable.type !== 'runnableByName') {
  // route to read_workspace_item with runnable.runType and its path instead
  return readWorkspaceItem(runnable.path)
}

Type guard

function isInlineRunnable(r) { return r && (r.type === 'inline' || r.type === 'runnableByName'); }

Try / catch

try { const { content } = resolveBackendFile(target, appPath) } catch (e) { if (String(e.message).includes('not inline')) return readWorkspaceItem(...); throw e }

Prevention

When it happens

Trigger: A tool call targeting a backend runnable whose entry in value.runnables[key] has a type other than 'inline' or 'runnableByName' (e.g. a referenced workspace script/flow), while trying to read/write its content via the backend file tools.

Common situations: The app was configured to reference a shared script or flow by path rather than embedding inline code; the model attempts to edit the referenced item's content as if it were inline.

Related errors


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