continuedev/continue · critical · Error

URL is not defined in params

Error message

URL is not defined in params

What it means

Thrown during VertexAI adapter construction when the parsed keyJson credentials do not produce a google-auth-library JWT client. The library calls auth.fromJSON(parsed) and expects a JWT instance (service-account style key) so it can attach Vertex AI scopes. Any other credential type (e.g. an API-key JSON or user-refresh credentials) fails this check.

Source

Thrown at core/commands/slash/built-in-legacy/http.ts:11

import { streamResponse } from "@continuedev/fetch";
import { SlashCommand } from "../../../index.js";
import { removeQuotesAndEscapes } from "../../../util/index.js";

const HttpSlashCommand: SlashCommand = {
  name: "http",
  description: "Call an HTTP endpoint to serve response",
  run: async function* ({ ide, llm, input, params, fetch }) {
    const url = params?.url;
    if (!url) {
      throw new Error("URL is not defined in params");
    }
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        input: removeQuotesAndEscapes(input),
      }),
    });

    // Stream the response
    if (response.body === null) {
      throw new Error("Response body is null");
    }
    for await (const chunk of streamResponse(response)) {
      yield chunk;
    }

View on GitHub (pinned to 5522c6f44c)

Solutions

  1. Download a proper service-account JSON key (IAM & Admin > Service Accounts > Keys) with roles/aiplatform.user and pass that as keyJson
  2. Verify the JSON has client_email and private_key fields before constructing the adapter
  3. If you only have an API key, use Vertex AI express mode (config.apiKey) with a gemini model instead of keyJson
  4. Ensure the private_key newlines survive transport (keep \n escapes; the adapter replaces them itself)

Example fix

// before
const api = new VertexAIApi({ keyJson: JSON.stringify({ key: process.env.GCP_API_KEY }) });

// after
const api = new VertexAIApi({ keyJson: fs.readFileSync('sa-key.json', 'utf8') }); // full service-account JSON
Defensive patterns

Strategy: validation

Validate before calling

function isServiceAccountJson(o: any): boolean {
  return !!o && typeof o === 'object'
    && typeof o.client_email === 'string' && o.client_email.endsWith('.iam.gserviceaccount.com')
    && typeof o.private_key === 'string' && o.private_key.includes('-----BEGIN PRIVATE KEY-----');
}
const parsed = JSON.parse(keyJson);
if (!isServiceAccountJson(parsed)) throw new Error('keyJson is not a service-account key');

Type guard

const isServiceAccount = (o: unknown): o is { client_email: string; private_key: string } =>
  typeof o === 'object' && o !== null &&
  typeof (o as any).client_email === 'string' &&
  typeof (o as any).private_key === 'string';

Try / catch

try { new VertexAIApi({ keyJson }); } catch (e) { if ((e as Error).message.includes('valid JWT')) throw new Error('Provide a service-account JSON key, not an API key'); throw e; }

Prevention

When it happens

Trigger: Passing config.keyJson that is valid JSON but not a Google service-account key — e.g. a GCP API key file, an unauthorized-client JSON, or a Vertex AI express-mode API key — so fromJSON returns a non-JWT AuthClient. Also triggered when private_key field is malformed after newline unescaping.

Common situations: Developer downloads the wrong key type from Google Cloud console (API key instead of service account JSON), copies a truncated key so \n escapes become literal newlines mid-key, or pastes a Firebase config object. Typical when migrating from OpenAI-style API keys to Vertex AI service-account auth.

Related errors


AI-assisted analysis of continuedev/continue@5522c6f44c (2026-08-27). Data as JSON: /api/errors/a51b79b8f37b29d0. Report an issue: GitHub.