different-ai/openwork · error · ApiError

invalid_env_key

invalid_env_key

Error message

Invalid environment variable name

What it means

The GET /env/:key route validates the :key path parameter with isValidEnvKey() and rejects it with a 400 invalid_env_key ApiError when it is not a valid environment variable name. This guards against malformed or malicious keys before the env store is queried. It is purely client-input validation.

Source

Thrown at apps/server/src/routes/core.ts:419

  addRoute(routes, "PUT", "/env/status", "host-token", async (ctx) => {
    const body = await readJsonBody(ctx.request);
    const runtimeKey = typeof body.runtimeKey === "string" && body.runtimeKey.trim()
      ? body.runtimeKey.trim()
      : "default";
    const pendingChanges = body.pendingChanges === true;
    if (pendingChanges) {
      envPendingChangesByRuntime.set(runtimeKey, true);
    } else {
      envPendingChangesByRuntime.delete(runtimeKey);
    }
    return jsonResponse({ runtimeKey, pendingChanges });
  });

  addRoute(routes, "GET", "/env/:key", "host-token", async (ctx) => {
    const key = ctx.params.key;
    if (!isValidEnvKey(key)) {
      throw new ApiError(400, "invalid_env_key", "Invalid environment variable name");
    }
    const item = (await env.list().catch(rethrowEnvStoreReadError)).find((entry) => entry.key === key);
    if (!item) {
      throw new ApiError(404, "env_not_found", "Environment variable not found");
    }
    return jsonResponse({
      item: {
        key: item.key,
        updatedAt: item.updatedAt,
        hasValue: item.value.length > 0,
        value: item.value,
      },
    });
  });

  addRoute(routes, "PUT", "/env", "host-token", async (ctx) => {
    ensureWritable(config);
    const body = await readJsonBody(ctx.request);

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Use a conventional env key: uppercase letters, digits, and underscores, not starting with a digit (e.g. MY_API_KEY)
  2. URL-encode the key with encodeURIComponent when building the request
  3. Trim whitespace and strip quotes from the key before sending
  4. Rename the variable on the producer side to a valid identifier

Example fix

// before
fetch(`/env/${key}`) // key = "my-var" -> 400
// after
const valid = /^[A-Za-z_][A-Za-z0-9_]*$/.test(key);
if (!valid) throw new Error(`invalid env key: ${key}`);
fetch(`/env/${encodeURIComponent(key)}`)
Defensive patterns

Strategy: validation

Validate before calling

const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
if (!ENV_KEY_RE.test(key)) throw new Error(`invalid env key: ${key}`);

Type guard

function isValidEnvKeyName(key: string): boolean {
  return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key);
}

Try / catch

try {
  const res = await api.get(`/env/${encodeURIComponent(key)}`);
} catch (e) {
  if (e.code === "invalid_env_key") throw new Error(`Key "${key}" is not a valid env name (use [A-Za-z_][A-Za-z0-9_]*)`);
  throw e;
}

Prevention

When it happens

Trigger: Calling GET /env/:key with a key containing characters outside the allowed set (e.g. spaces, '=', '-', unicode, empty string after decoding) or URL-encoding problems where the decoded key is invalid.

Common situations: A client builds the URL by string concatenation instead of encodeURIComponent; a key with lowercase/dashes convention from another system (e.g. 'my-var') is rejected; a script iterates keys from a file containing comments or blanks.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/2868894149c6c8aa. Report an issue: GitHub.