windmill-labs/windmill · error
'${target.path}' does not match runnable '${target.key}' lan
Error message
'${target.path}' does not match runnable '${target.key}' language. Use backend/${target.key}/main.${expectedExtension}. What it means
For inline backend runnables, applyPatch enforces that the patch path's extension matches the runnable's script language: TypeScript runnables use main.ts, Python (python3) runnables use main.py (getBackendInlineScriptExtension). This error is thrown when the extension in the path disagrees with the runnable's actual language.
Source
Thrown at frontend/src/lib/components/copilot/chat/app/core.ts:631
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,
replaceAll,
'current file content'
)
toolCallbacks.setToolStatus(toolId, {
content: `Patching '${target.path}'...`
})View on GitHub (pinned to e474e8803c)
Solutions
- Use the extension matching the runnable's language: backend/<key>/main.ts for TypeScript, backend/<key>/main.py for python3
- Check inlineScript.language on the runnable before constructing the path
- If the language itself is wrong, change the runnable's language through the app definition rather than patching a mismatched file
Example fix
// before
applyPatch({ path: 'backend/etl/main.ts', ... }) // runnable.language = python3
// after
applyPatch({ path: 'backend/etl/main.py', ... }) Defensive patterns
Strategy: validation
Validate before calling
const expected = runnable.inlineScript?.language === 'python3' ? 'py' : 'ts'
if (!path.endsWith(`main.${expected}`)) {
throw new Error(`Use backend/${key}/main.${expected} for this runnable`)
} Type guard
function pathMatchesRunnableLanguage(path: string, r: BackendRunnable): boolean {
const expected = r.inlineScript?.language === 'python3' ? 'py' : 'ts'
return path.endsWith(`main.${expected}`)
} Try / catch
try {
await patchTool({ path, ... })
} catch (e) {
const m = e instanceof Error && e.message.match(/Use (backend\/.*)\./)
if (m) { return patchTool({ path: m[1], ... }) } // retry with corrected extension
throw e
} Prevention
- Read inlineScript.language before constructing the patch path
- Default to .ts only when the language is confirmed TypeScript
- Regenerate file listings after any language change to a runnable
When it happens
Trigger: Patching 'backend/step/main.py' when the runnable's inlineScript.language is not python3 (defaults to ts), or patching 'main.ts' for a Python runnable. resolveAppPatchTarget only matches .ts/.py paths, but either can be chosen regardless of the runnable's real language.
Common situations: Model assuming Python for a TS step; a runnable whose language was changed after the model read an older file listing; generated paths defaulting to .ts for Python-heavy apps.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- '/wmill.d.ts' is generated automatically. Edit backend runna
- Frontend file '${target.path}' not found.
- Backend runnable '${target.key}' not found.
- '${target.path}' points to backend runnable '${target.key}',
- Cannot push flow ${remotePath}: step(s) reference non-worksp
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/08b50d0a45302f3e.
Report an issue: GitHub.