windmill-labs/windmill · error · Error
"${args.value}" is not a valid value for variable "${args.pa
Error message
"${args.value}" is not a valid value for variable "${args.path}" — it is a self-reference. Omit value to keep the current one. What it means
The AI chat's write_variable tool throws this when the model passes the literal string "$var:<same path>" as the new value of the variable it is updating. A Windmill variable's value is never interpolated, so such a value is always the model echoing the reference syntax back rather than a real value. The tool rejects it and asks the model to omit the value field to keep the current one.
Source
Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:5109
ctx: WriteDraftCtx
): Promise<string> {
return writeDraft(RESOURCE_SPEC, 'resource', args.path, args, ctx, { override: args.override })
}
const VARIABLE_SPEC: WriteSpec<VariableDraftState, WriteVariableArgs> = {
probe: (workspace, path) => VariableService.existsVariable({ workspace, path }),
fetchDeployed: async (workspace, path) =>
variableToDraftState(
await VariableService.getVariable({ workspace, path, decryptSecret: false })
),
buildDraft: (base, args) => createVariableToDraftState(args, base)
}
function writeVariableDraft(args: WriteVariableArgs, ctx: WriteDraftCtx): Promise<string> {
// A variable's value is never interpolated, so "$var:<its own path>" as the value
// is always the model echoing the reference syntax back instead of a real value.
if (args.value === `$var:${args.path}`) {
throw new Error(
`"${args.value}" is not a valid value for variable "${args.path}" — it is a self-reference. Omit value to keep the current one.`
)
}
return writeDraft(VARIABLE_SPEC, 'variable', args.path, args, ctx, { override: args.override })
}
async function loadScriptForEdit(
path: string,
workspace: string
): Promise<{ content: string; language: ScriptLang; summary?: string }> {
const draft = await getGlobalDraft(workspace, 'script', path)
if (draft) {
if (typeof draft.value !== 'string' || !draft.language) {
throw new Error(`Draft script "${path}" is missing content or language.`)
}
return { content: draft.value, language: draft.language, summary: draft.summary }
}
const script = await ScriptService.getScriptByPath({ workspace, path })View on GitHub (pinned to e474e8803c)
Solutions
- Omit the `value` argument in the write_variable call so the current value is kept.
- If a real new value is intended, pass the actual value string instead of the $var: reference syntax.
- If the goal is to reference another item, use the correct resource/reference type (e.g. resource) instead of a variable self-reference.
Example fix
// before
writeVariable({ path: 'f/my/var', value: '$var:f/my/var' })
// after
writeVariable({ path: 'f/my/var' }) // omit value to keep current one
// or
writeVariable({ path: 'f/my/var', value: 'actual-value' }) Defensive patterns
Strategy: validation
Validate before calling
if (args.value === `$var:${args.path}`) {
// skip sending value; keep current variable value
delete args.value
} Type guard
function isSelfReference(value: unknown, path: string): boolean {
return typeof value === 'string' && value === `$var:${path}`
} Try / catch
try {
await writeVariable(args)
} catch (e) {
if (String(e.message).includes('self-reference')) {
await writeVariable({ ...args, value: undefined })
} else throw e
} Prevention
- Never pass $var:<path> syntax as a variable value; variables are not interpolated.
- Omit `value` entirely when the intent is to keep the current value.
- Use resources, not variables, for reference-style values.
When it happens
Trigger: Calling the write_variable tool (writeVariableDraft) with args.value exactly equal to `$var:${args.path}`, where args.path is the same variable path being written.
Common situations: The model misreads a variable reference found in scripts/config as the variable's actual value and copies it back verbatim; user asks to 'keep the variable as its own reference'; hallucinated round-trip of interpolation syntax during multi-step edits.
Related errors
- result.substring(__RESULT_ERR_PREFIX.length)
- Invalid migration name '${name}': use only letters, digits,
- Unknown workspace dependencies file format: ${path}. Valid f
- Cannot push flow ${remotePath}: step(s) reference non-worksp
- Completed jobs file must contain an array of jobs
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/546741287ed251fb.
Report an issue: GitHub.