windmill-labs/windmill · error · Error

Frontend file "${target.filePath}" not found in app "${args.

Error message

Frontend file "${target.filePath}" not found in app "${args.path}".

What it means

When reading an app's content, frontend files are looked up by key in the app value's `files` map. If the requested filePath key is absent, the app value has no such frontend file and the tool throws. Inline runnable targets take a different path (getInlineRunnableContent) and do not produce this error.

Source

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

		file_path: string
		offset?: number
		limit?: number
	},
	ctx: WriteDraftCtx
): Promise<string> {
	const { workspace, toolId, toolCallbacks } = ctx
	const target = resolveAppFileTarget(args.file_path)
	toolCallbacks.setToolStatus(toolId, {
		content: `Reading ${target.filePath} from app "${args.path}"...`
	})

	const value = await loadAppValueForRead(args.path, workspace)

	let content: string
	if (target.kind === 'frontend') {
		const frontend = value.files[target.filePath]
		if (frontend === undefined) {
			throw new Error(`Frontend file "${target.filePath}" not found in app "${args.path}".`)
		}
		content = frontend
	} else {
		content = getInlineRunnableContent(value, target, args.path).content
	}

	const slice = sliceAppFileForRead(content, args.offset, args.limit)

	toolCallbacks.setToolStatus(toolId, { content: `Read ${target.filePath}` })
	return formatAppFileReadResult(slice)
}

// search_app caps: a single query must stay sparse and cheap even when it hits a
// minified bundle or a 5k-line data module. Per-line and total-output caps bound
// the result the same way read_app_file's char budget bounds one file read; the
// match cap keeps a broad query from flooding context instead of locating it.
const SEARCH_APP_DEFAULT_MAX_MATCHES = 100
const SEARCH_APP_MAX_MATCHES_CEILING = 200

View on GitHub (pinned to e474e8803c)

Solutions

  1. List the app's actual files first (read the app structure) and retry with an exact existing filePath key.
  2. Check path spelling and case against the app's file map.
  3. Create the missing file with write_app_file if it should exist.

Example fix

// before
readAppFile({ path: 'f/myapp', filePath: 'src/App.svelte' }) // app uses flat layout
// after
readAppFile({ path: 'f/myapp', filePath: 'App.svelte' })
Defensive patterns

Strategy: validation

Validate before calling

const value = await loadAppValueForRead(args.path, workspace)
if (!(target.filePath in value.files)) {
  console.warn('available:', Object.keys(value.files))
}

Type guard

function hasFrontendFile(value: AppValue, filePath: string): boolean {
  return Object.prototype.hasOwnProperty.call(value.files ?? {}, filePath)
}

Try / catch

try {
  content = await readAppFile(args)
} catch (e) {
  if (e.message.startsWith('Frontend file')) {
    const value = await loadAppValueForRead(args.path, workspace)
    // retry with an exact key from Object.keys(value.files)
  } else throw e
}

Prevention

When it happens

Trigger: Calling the read-app-content tool with a target of kind 'frontend' where value.files[target.filePath] === undefined for app args.path (draft or deployed).

Common situations: Typo'd or wrong-cased file path; requesting a file that only exists in a different app; the file was deleted or never created in the app draft; assuming a default file name that the template did not generate.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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