windmill-labs/windmill · error
file only applies to multi-file apps; ${entry.kind} "${path}
Error message
file only applies to multi-file apps; ${entry.kind} "${path}" diffs as a single document — call again without file. What it means
Mirror of error 412 for the fork-comparison path: the `file` argument only applies to multi-file apps. When the fork diff entry has no `files` map (single-document kind, or only_in_fork/only_in_parent content dumps without file granularity), passing `file` throws this corrective error telling the caller to retry without it.
Source
Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:7041
const changedFileCount = entry.files ? Object.keys(entry.files).length : 0
if (entry.status === 'unchanged' || (!entry.patch && changedFileCount === 0)) {
// A masked value can differ in content without producing a patch —
// never report that as "same content".
const message = entry.valueMasked
? `${entry.kind} "${path}": no visible config differences vs parent "${parent}", but variable values are never shown in chat, so a value change cannot be displayed. The workspace comparison reports it as ${entry.ahead > 0 || entry.behind > 0 ? `differing (ahead ${entry.ahead}, behind ${entry.behind})` : 'in sync'}.`
: entry.kind === 'folder'
? `folder "${path}": no comparable differences vs parent "${parent}" — the folder display name is not exposed by the API and may be what differs (comparison reports ahead ${entry.ahead}, behind ${entry.behind}).`
: `${entry.kind} "${path}" has the same content in the fork and its parent "${parent}" (only version history differs).`
return draftCaveat + message
}
const header =
entry.status === 'only_in_fork'
? `${entry.kind} "${path}" exists only in the fork — not in parent "${parent}". Full content:\n\n`
: entry.status === 'only_in_parent'
? `${entry.kind} "${path}" exists only in parent "${parent}" — not in the fork. Parent content:\n\n`
: `Fork changes vs parent "${parent}" for ${entry.kind} "${path}":\n\n`
if (args.file !== undefined && !entry.files) {
throw new Error(
`file only applies to multi-file apps; ${entry.kind} "${path}" diffs as a single document — call again without file.`
)
}
const body = entry.files
? renderEntryFiles(entry.files, entry.patch ?? '', args)
: windowPatchBody(entry.patch ?? '', args.offset ?? 0, args.limit ?? DIFF_READ_DEFAULT_LINES)
return draftCaveat + header + body
}
const DIFF_SEARCH_DEFAULT_MAX_MATCHES = 50
const DIFF_SEARCH_MAX_MATCHES_CEILING = 200
interface DiffSearchUnit {
/** Item path, or `${itemPath}/${fileName}` for a file inside an app. */
subject: string
patch: string
}
View on GitHub (pinned to e474e8803c)
Solutions
- Retry without the `file` argument
- For multi-file apps, verify the entry exposes files (type 'app'/'raw_app' with a computed comparison) before narrowing
Example fix
// before
diffFork({ type: 'script', path: 'f/build', file: 'main.ts' })
// after
diffFork({ type: 'script', path: 'f/build' }) Defensive patterns
Strategy: validation
Validate before calling
if (args.file !== undefined && entry.files === undefined) {
// single-document fork diff: drop file before calling
delete args.file
} Type guard
function entryHasFiles(entry: { files?: Record<string, unknown> }): boolean {
return entry.files !== undefined
} Try / catch
try {
return await diffFork(args)
} catch (e) {
if (String(e?.message).startsWith('file only applies to multi-file apps')) {
return await diffFork({ ...args, file: undefined })
}
throw e
} Prevention
- Only pass `file` when the fork entry exposes a files map
- Drop `file` on retry after this error
- Remember only_in_fork/only_in_parent entries are single-document dumps
When it happens
Trigger: Calling the fork diff tool with `args.file` set while `entry.files` is undefined — e.g. diffing a script or a flow against the parent, or an only_in_fork item whose full content is returned as a single document.
Common situations: Agents reusing the `file` argument across calls after diffing an app; assuming parent-side apps always expose file granularity (older comparison data may not include files).
Related errors
- Workspace "${workspace}" is not a fork — it has no parent wo
- path is required.
- Missing required arguments: ${required.join(", ")}. Use -d '
- file only applies to multi-file apps; ${type} "${path}" diff
- search requires a non-empty string.
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/23d0999a860d6619.
Report an issue: GitHub.