decolua/9router · error · MissingBaseUrlError

Missing base URL

Error message

Missing base URL

What it means

Raised by the self-hosted embedding adapter's buildUrl (open-sse/handlers/embeddingProviders/selfhostedEmbedding.js:40) as a MissingBaseUrlError when a Self-hosted Embedding connection has no providerSpecificData.baseUrl. Unlike the generic OpenAI-compatible adapter, this adapter deliberately refuses to fall back to https://api.openai.com/v1 — doing so would silently send the user's local embedding input text and API key to OpenAI. An empty baseUrl is treated as a hard configuration error (isConfigError = true).

Source

Thrown at open-sse/handlers/embeddingProviders/selfhostedEmbedding.js:40

export class MissingBaseUrlError extends Error {
  constructor() {
    super(
      "Self-hosted Embedding needs an endpoint: set this connection's baseUrl to " +
        "the OpenAI base URL of your server, e.g. http://host:8080/v1 (note the /v1 — " +
        "\"/embeddings\" is appended to it). Refusing to fall back to api.openai.com, " +
        "which would send your input and API key to OpenAI."
    );
    this.name = "MissingBaseUrlError";
    this.isConfigError = true;
  }
}

export default {
  ...baseAdapter,
  buildUrl: (_model, creds) => {
    const rawBaseUrl = creds?.providerSpecificData?.baseUrl;
    if (!rawBaseUrl || !String(rawBaseUrl).trim()) throw new MissingBaseUrlError();
    // Accept either the OpenAI base or a full embeddings URL, so a value pasted
    // from a curl example works as well as one typed from the help text.
    const baseUrl = String(rawBaseUrl).trim().replace(/\/$/, "").replace(/\/embeddings$/, "");
    return `${baseUrl}/embeddings`;
  },
};

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Edit the Self-hosted Embedding connection and set baseUrl to your server's OpenAI-compatible base, e.g. http://localhost:8080/v1 ('/embeddings' is appended automatically).
  2. Include the /v1 segment — the adapter only strips a trailing '/embeddings', it does not add a version path.
  3. If you were re-importing credentials, re-add providerSpecificData: { baseUrl: "http://host:8080/v1" } to the credential JSON.
  4. Full/embeddings URLs also work: http://host:8080/v1/embeddings is normalized to the base automatically.

Example fix

// before
{ "providerSpecificData": {} }
// after
{ "providerSpecificData": { "baseUrl": "http://localhost:8080/v1" } }
Defensive patterns

Strategy: validation

Validate before calling

const baseUrl = creds?.providerSpecificData?.baseUrl;
if (!baseUrl || !String(baseUrl).trim()) {
  throw new Error("Self-hosted Embedding requires providerSpecificData.baseUrl, e.g. http://host:8080/v1");
}

Type guard

function hasSelfhostedBaseUrl(creds) {
  const b = creds?.providerSpecificData?.baseUrl;
  return typeof b === "string" && b.trim().length > 0;
}

Try / catch

try {
  await embed(texts);
} catch (e) {
  if (e.name === "MissingBaseUrlError" || /Missing base URL/.test(e.message)) {
    openConnectionSettingsAndFocusBaseUrlField();
  } else throw e;
}

Prevention

When it happens

Trigger: An embedding request targets the 'selfhosted-embedding' provider and creds.providerSpecificData.baseUrl is undefined, null, or whitespace-only. Typically a connection was saved without filling the endpoint field, or providerSpecificData was dropped during credential import/export.

Common situations: User created the connection and left 'Base URL' blank assuming a default exists; baseUrl was cleared when editing other fields; credential JSON migrated from another tool omits providerSpecificData; trailing whitespace-only value pasted into the field.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/74418026994a5e0d. Report an issue: GitHub.