{"record":{"id":"546741287ed251fb","repo":"windmill-labs/windmill","slug":"args-value-is-not-a-valid-value-for-variable","errorCode":null,"errorMessage":"\"${args.value}\" is not a valid value for variable \"${args.path}\" — it is a self-reference. Omit value to keep the current one.","messagePattern":"\"(.+?)\" is not a valid value for variable \"(.+?)\" — it is a self-reference\\. Omit value to keep the current one\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/global/core.ts","lineNumber":5109,"sourceCode":"\tctx: WriteDraftCtx\n): Promise<string> {\n\treturn writeDraft(RESOURCE_SPEC, 'resource', args.path, args, ctx, { override: args.override })\n}\n\nconst VARIABLE_SPEC: WriteSpec<VariableDraftState, WriteVariableArgs> = {\n\tprobe: (workspace, path) => VariableService.existsVariable({ workspace, path }),\n\tfetchDeployed: async (workspace, path) =>\n\t\tvariableToDraftState(\n\t\t\tawait VariableService.getVariable({ workspace, path, decryptSecret: false })\n\t\t),\n\tbuildDraft: (base, args) => createVariableToDraftState(args, base)\n}\n\nfunction writeVariableDraft(args: WriteVariableArgs, ctx: WriteDraftCtx): Promise<string> {\n\t// A variable's value is never interpolated, so \"$var:<its own path>\" as the value\n\t// is always the model echoing the reference syntax back instead of a real value.\n\tif (args.value === `$var:${args.path}`) {\n\t\tthrow new Error(\n\t\t\t`\"${args.value}\" is not a valid value for variable \"${args.path}\" — it is a self-reference. Omit value to keep the current one.`\n\t\t)\n\t}\n\treturn writeDraft(VARIABLE_SPEC, 'variable', args.path, args, ctx, { override: args.override })\n}\n\nasync function loadScriptForEdit(\n\tpath: string,\n\tworkspace: string\n): Promise<{ content: string; language: ScriptLang; summary?: string }> {\n\tconst draft = await getGlobalDraft(workspace, 'script', path)\n\tif (draft) {\n\t\tif (typeof draft.value !== 'string' || !draft.language) {\n\t\t\tthrow new Error(`Draft script \"${path}\" is missing content or language.`)\n\t\t}\n\t\treturn { content: draft.value, language: draft.language, summary: draft.summary }\n\t}\n\tconst script = await ScriptService.getScriptByPath({ workspace, path })","sourceCodeStart":5091,"sourceCodeEnd":5127,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/global/core.ts#L5091-L5127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nwriteVariable({ path: 'f/my/var', value: '$var:f/my/var' })\n// after\nwriteVariable({ path: 'f/my/var' }) // omit value to keep current one\n// or\nwriteVariable({ path: 'f/my/var', value: 'actual-value' })","handlingStrategy":"validation","validationCode":"if (args.value === `$var:${args.path}`) {\n  // skip sending value; keep current variable value\n  delete args.value\n}","typeGuard":"function isSelfReference(value: unknown, path: string): boolean {\n  return typeof value === 'string' && value === `$var:${path}`\n}","tryCatchPattern":"try {\n  await writeVariable(args)\n} catch (e) {\n  if (String(e.message).includes('self-reference')) {\n    await writeVariable({ ...args, value: undefined })\n  } else throw e\n}","preventionTips":["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."],"tags":["validation","variables","ai-tooling"],"backgroundTag":"self-reference-value-rejected","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"}