{"record":{"id":"71b9a610058cf191","repo":"windmill-labs/windmill","slug":"draft-app-path-has-no-policy-to-deploy","errorCode":null,"errorMessage":"Draft app \"${path}\" has no policy to deploy.","messagePattern":"Draft app \"(.+?)\" has no policy to deploy\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/global/core.ts","lineNumber":7415,"sourceCode":"\t\t\t\t\t\t: undefined\n\t\t\t\t\tassertDraftBasedOnLatest(\n\t\t\t\t\t\t'app',\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\tdraft.parentVersionId,\n\t\t\t\t\t\tdeployedApp?.versions?.[deployedApp.versions.length - 1],\n\t\t\t\t\t\tforce\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tconst appValue: AppDraftValue = {\n\t\t\t\t\t...appDraft,\n\t\t\t\t\tfiles: { ...(appDraft.files ?? {}) },\n\t\t\t\t\trunnables: { ...(appDraft.runnables ?? {}) },\n\t\t\t\t\tdata: appDraft.data ?? { ...DEFAULT_RAW_APP_DATA }\n\t\t\t\t}\n\t\t\t\tawait recomputeAppPolicy(appValue)\n\t\t\t\tconst policy = appValue.policy\n\t\t\t\tif (!policy) {\n\t\t\t\t\tthrow new Error(`Draft app \"${path}\" has no policy to deploy.`)\n\t\t\t\t}\n\n\t\t\t\t// An app deployed on its own while a path runnable still points at a draft\n\t\t\t\t// is deployed and broken — the deploy has to say so, not just report success.\n\t\t\t\tconst undeployedTargets = await undeployedRunnableTargets(workspace, appValue.runnables)\n\t\t\t\tif (undeployedTargets.length > 0) {\n\t\t\t\t\tdeployNote =\n\t\t\t\t\t\t`These backend runnables point at items that are NOT deployed, so they fail at runtime: ` +\n\t\t\t\t\t\t`${undeployedTargets.join(', ')}. Deploy those items too, and tell the user the app is ` +\n\t\t\t\t\t\t`not working until they are.`\n\t\t\t\t}\n\n\t\t\t\ttoolCallbacks.setToolStatus(toolId, {\n\t\t\t\t\tcontent: `Bundling app \"${path}\"...`\n\t\t\t\t})\n\t\t\t\tconst bundle = await bundleRawAppDraft({\n\t\t\t\t\tworkspace,\n\t\t\t\t\tfiles: appValue.files,","sourceCodeStart":7397,"sourceCodeEnd":7433,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/global/core.ts#L7397-L7433","documentation":"Thrown while deploying a raw app draft in the chat's deployDraft tool. Before deploying, the tool recomputes the app's policy (recomputeAppPolicy) from its runnables and data; if the resulting appValue.policy is falsy, there is no permission policy to ship, and deploying would leave the app without access rules. The tool aborts and asks for a draft with a computed policy.","triggerScenarios":"Deploying a raw_app whose draft, after policy recomputation, yields appValue.policy == null — e.g. malformed/absent policy-producing fields in the draft (runnables/data shape the policy computer cannot derive a policy from).","commonSituations":"A raw app draft created by the AI with a runnables/data shape missing what rawAppPolicy expects; hand-edited draft state that dropped the policy section; a DEFAULT_RAW_APP_DATA regression after schema changes.","solutions":["Open the raw app draft and ensure its runnables/data are well-formed so a policy can be computed, then redeploy.","Check the draft against DEFAULT_RAW_APP_DATA to spot missing fields the policy derivation relies on.","If recomputation is failing on valid data, investigate recomputeAppPolicy / rawAppPolicy for a regression."],"exampleFix":"// before: draft.data missing expected sections\nawait deployDraft({ type: 'raw_app', path: 'a/admin_panel' })\n// Error: Draft raw_app \"a/admin_panel\" has no policy to deploy.\n\n// after: restore the draft's data/runnables so recomputeAppPolicy derives a policy\nappDraft.data = { ...DEFAULT_RAW_APP_DATA, ...edits }\nawait deployDraft({ type: 'raw_app', path: 'a/admin_panel' })","handlingStrategy":"validation","validationCode":"import { DEFAULT_RAW_APP_DATA } from '$lib/components/raw_apps/rawAppData'\nconst appDraft = (await getGlobalDraft(ws, 'raw_app', path))?.value\nif (appDraft && (!appDraft.runnables || !appDraft.data)) {\n  appDraft.data = { ...DEFAULT_RAW_APP_DATA, ...(appDraft.data ?? {}) }\n}\nawait deployDraft({ type: 'raw_app', path, workspace: ws })","typeGuard":"function rawAppDraftHasPolicyInputs(draft) {\n  return draft != null && draft.value != null &&\n    typeof draft.value === 'object' && 'runnables' in draft.value && 'data' in draft.value\n}","tryCatchPattern":"try {\n  await deployDraft({ type: 'raw_app', path, workspace })\n} catch (e) {\n  if (/has no policy to deploy/.test(e.message)) {\n    // repair the draft's runnables/data in the editor, then retry\n  } else throw e\n}","preventionTips":["Build raw app drafts on top of DEFAULT_RAW_APP_DATA instead of from scratch.","Don't strip policy-relevant fields when programmatically editing drafts.","Preview the app in the editor (which computes the policy) before deploying."],"tags":["raw-app","policy","deploy","validation"],"backgroundTag":"missing-app-policy","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}