{"record":{"id":"a0fe3728a683c74f","repo":"windmill-labs/windmill","slug":"draft-variable-draftvalue-path-is-secret-but","errorCode":null,"errorMessage":"Draft variable \"${draftValue.path}\" is secret but stages no value, so it cannot be created. Run write_variable with its value first.","messagePattern":"Draft variable \"(.+?)\" is secret but stages no value, so it cannot be created\\. Run write_variable with its value first\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/global/core.ts","lineNumber":4732,"sourceCode":"\t\tpath: args.path,\n\t\tvariable: {\n\t\t\tvalue,\n\t\t\tis_secret,\n\t\t\tdescription\n\t\t},\n\t\tlabels: args.labels ?? base?.labels,\n\t\twsSpecific: args.ws_specific ?? base?.wsSpecific ?? false,\n\t\taccount: args.account ?? base?.account,\n\t\tis_oauth: args.is_oauth ?? base?.is_oauth,\n\t\texpires_at: args.expires_at ?? base?.expires_at\n\t}\n}\n\n// The deploy body for a variable that does not exist yet.\nfunction buildVariableCreateRequestBody(draftValue: CreateVariable): CreateVariable {\n\tconst requestBody = structuredClone(draftValue)\n\tif (requestBody.is_secret && requestBody.value === '') {\n\t\tthrow new Error(\n\t\t\t`Draft variable \"${draftValue.path}\" is secret but stages no value, so it cannot be created. Run write_variable with its value first.`\n\t\t)\n\t}\n\treturn requestBody\n}\n\n// The deploy body for an existing variable. Every field is optional on the update\n// endpoint, and a draft stores '' when it stages no new value — so omitting `value` in\n// that case is what leaves the stored one untouched. A staged value is sent as-is: the\n// endpoint decrypts an `$encrypted:` marker and encrypts plaintext.\nfunction buildVariableUpdateRequestBody(\n\tdraftValue: CreateVariable\n): Omit<CreateVariable, 'value'> & { value?: string } {\n\tconst { value, ...rest } = structuredClone(draftValue)\n\t// A value the draft is never allowed to carry — a secret's, and an OAuth-managed one\n\t// dropped by `variableToDraftState` — reaches here as '' whenever this edit staged\n\t// none, so sending it would blank the stored value or wipe a rotating token.\n\tif (rest.is_secret || rest.is_oauth === true || rest.account != undefined) {","sourceCodeStart":4714,"sourceCodeEnd":4750,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/global/core.ts#L4714-L4750","documentation":"When deploying a new variable that does not exist yet, a secret variable must carry a staged value. If the draft's value is '' (the 'nothing staged' sentinel), the backend would create an empty secret, so this error tells the model to stage the value first.","triggerScenarios":"Deploying a draft variable whose requestBody.is_secret is true and value is '' — i.e. buildVariableCreateRequestBody on a create-body with no staged value.","commonSituations":"The model created a variable draft and forgot to stage a value (or used '' as placeholder) before triggering the deploy.","solutions":["Run write_variable with the actual value for the draft path first, then redeploy","If the variable should not be secret, set is_secret: false so an empty value is allowed"],"exampleFix":"// before\ndeployVariables([{ path: 'u/admin/API_KEY', is_secret: true, value: '' }])\n// after\nwriteVariable({ path: 'u/admin/API_KEY', is_secret: true, value: 'abc123' })\ndeployVariables([{ path: 'u/admin/API_KEY', is_secret: true, value: 'abc123' }])","handlingStrategy":"validation","validationCode":"if (draft.is_secret && draft.value === '') throw new Error('stage the secret value before deploying');","typeGuard":"function isDeployableSecretDraft(d) { return !d.is_secret || (typeof d.value === 'string' && d.value !== ''); }","tryCatchPattern":"try { deployVariables(drafts) } catch (e) { if (e.message.includes('stages no value')) await writeVariable({ path, value }) and redeploy; }","preventionTips":["Stage a value with write_variable before deploying secret drafts","Never deploy secret drafts with value '' (the nothing-staged sentinel)"],"tags":["ai-copilot","secrets","variables","deploy"],"backgroundTag":"empty-secret-value","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"}