windmill-labs/windmill · error

'${target.path}' points to backend runnable '${target.key}',

Error message

'${target.path}' points to backend runnable '${target.key}', but only inline runnables can be patched as files.

What it means

Backend runnables can only be patched as files when they are inline scripts (with inlineScript content). Runnables that reference an external path/path-based script or lack inline content cannot be text-patched, so applyPatch throws this error naming both the path and the runnable key. It prevents corrupting a runnable whose source lives outside the app file.

Source

Thrown at frontend/src/lib/components/copilot/chat/app/core.ts:624

			if (target.type === 'frontend') {
				if (target.path === '/wmill.d.ts') {
					throw new Error(
						"'/wmill.d.ts' is generated automatically. Edit backend runnables instead."
					)
				}

				const frontendContent = helpers.getFrontendFile(target.path)
				if (frontendContent === undefined) {
					throw new Error(`Frontend file '${target.path}' not found.`)
				}
				currentContent = frontendContent
			} else {
				backendRunnable = helpers.getBackendRunnable(target.key)
				if (!backendRunnable) {
					throw new Error(`Backend runnable '${target.key}' not found.`)
				}
				if (backendRunnable.type !== 'inline' || !backendRunnable.inlineScript) {
					throw new Error(
						`'${target.path}' points to backend runnable '${target.key}', but only inline runnables can be patched as files.`
					)
				}

				const expectedExtension = getBackendInlineScriptExtension(backendRunnable)
				if (target.extension !== expectedExtension) {
					throw new Error(
						`'${target.path}' does not match runnable '${target.key}' language. Use backend/${target.key}/main.${expectedExtension}.`
					)
				}

				currentContent = backendRunnable.inlineScript.content ?? ''
			}

			const updatedContent = findAndReplace(
				currentContent,
				oldString,
				newString,

View on GitHub (pinned to e474e8803c)

Solutions

  1. Open the referenced script by its path in the script editor and edit it there instead of patching the app file
  2. Convert the runnable to an inline script if the app design allows, then patch it
  3. Choose a different backend runnable that is inline, or add a new inline runnable for the change
Defensive patterns

Strategy: type-guard

Validate before calling

const r = helpers.getBackendRunnable(key)
if (r && (r.type !== 'inline' || !r.inlineScript)) {
  throw new Error(`Runnable ${key} is not inline; edit its referenced script by path instead`)
}

Type guard

function isInlineRunnable(r: BackendRunnable | undefined): r is BackendRunnable & { type: 'inline'; inlineScript: NonNullable<BackendRunnable['inlineScript']> } {
  return !!r && r.type === 'inline' && !!r.inlineScript
}

Try / catch

try {
  await patchTool({ path, ... })
} catch (e) {
  if (e instanceof Error && e.message.includes('only inline runnables can be patched')) {
    toolCallbacks.report('Open the referenced script in the script editor to change it')
    return
  }
  throw e
}

Prevention

When it happens

Trigger: Patching 'backend/<key>/main.ts' where getBackendRunnable(key) exists but its type is not 'inline' or inlineScript is undefined — e.g. the runnable points to a script by path, is a hub/flow reference, or the inline script body was never set.

Common situations: Apps whose steps are reused scripts stored in the script library (path-referenced) rather than inline code; converted apps; model assuming every backend step is editable inline.

Related errors


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