windmill-labs/windmill · error · Error

Variable not found at ${path} or not visible to you: ${e.bod

Error message

Variable not found at ${path} or not visible to you: ${e.body}

What it means

getVariable() fetches a variable's value by path via VariableService.getVariableValue. Any API error is rethrown with this message — covering both a genuinely missing path and permission/visibility problems, since Windmill hides variables the caller cannot see (404-style responses for both). The server's error body is appended for diagnosis.

Source

Thrown at typescript-client/client.ts:788

 * @returns variable value
 */
export async function getVariable(path: string): Promise<string> {
  path = parseVariableSyntax(path) ?? path;
  const mockedApi = await getMockedApi();
  if (mockedApi) {
    if (mockedApi.variables[path]) {
      return mockedApi.variables[path];
    } else {
      console.log(
        `MockedAPI present, but variable not found at ${path}, falling back to real API`
      );
    }
  }
  const workspace = getWorkspace();
  try {
    return await VariableService.getVariableValue({ workspace, path });
  } catch (e: any) {
    throw Error(
      `Variable not found at ${path} or not visible to you: ${e.body}`
    );
  }
}

/**
 * Set a variable by path, create if not exist
 * @param path path of the variable
 * @param value value of the variable
 * @param isSecretIfNotExist if the variable does not exist, create it as secret or not (default: false)
 * @param descriptionIfNotExist if the variable does not exist, create it with this description (default: "")
 */
export async function setVariable(
  path: string,
  value: string,
  isSecretIfNotExist?: boolean,
  descriptionIfNotExist?: string
): Promise<void> {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Verify the exact variable path in the Windmill UI (Variables page) — copy it rather than retyping.
  2. Confirm the variable exists in the workspace your script runs in (WM_WORKSPACE), and your token has read access to it.
  3. Create the missing variable (`wmill variable create` or UI) with the same path.
  4. Check e.body in the message: 404 usually means missing or hidden; 403 means permissions.
  5. Use $variables syntax or wmill variable list to audit references before renaming/deleting.

Example fix

// before
const apiKey = await getVariable('f/deployment/api_key');
// after
try {
  const apiKey = await getVariable('f/deployment/api_key');
} catch (e) {
  console.error('variable missing or not visible; check path/permissions in this workspace');
  throw e;
}
Defensive patterns

Strategy: validation

Validate before calling

import { VariableService } from './sdk';
const vars = await VariableService.listVariables({ workspace }); // or `wmill variable list`
if (!vars.some((v) => v.path === path)) {
  throw new Error(`Variable ${path} must be provisioned before running`);
}

Try / catch

let apiKey: string;
try {
  apiKey = await getVariable('f/deployment/api_key');
} catch (e) {
  console.error(`Variable lookup failed: ${e.message}`); // includes server e.body
  throw new Error(`Required variable missing or not visible in this workspace`);
}

Prevention

When it happens

Trigger: Calling getVariable('f/...') or getVariable('u/...') with a typo'd/non-existent path; the variable is secret and the token/workspace lacks permission; the variable lives in another workspace; getVariable('$res:...')-style syntax confusion after parseVariableSyntax; path with stale variable reference in a deployed script.

Common situations: Renaming or deleting a variable while scripts still reference it; CI token without variable read scope; copying a script across workspaces; promoting code between dev/prod instances where the variable wasn't recreated.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/39a4af4b109be720. Report an issue: GitHub.