langgenius/dify · error · BaseError

UsageInvalidFlag

UsageInvalidFlag

Error message

host parse: ${(err as Error).message}

What it means

BaseError(UsageInvalidFlag, exit 2) from resolveHost (host.ts:24) when `new URL(raw)` throws. Before reaching URL, resolveHost trims, defaults empty to DEFAULT_HOST (https://cloud.dify.ai), and prepends 'https://' if no '://' is present — so the parse only fails on values that remain malformed even after those fixes: embedded spaces, control chars, invalid percent-encoding, or a scheme that URL rejects. The original parser message is appended (e.g. 'Invalid URL').

Source

Thrown at cli/src/util/host.ts:24

export function openAPIBase(host: string): string {
  return `${host.replace(/\/+$/, '')}/openapi/v1/`
}

export type ResolveHostOptions = {
  raw: string
  insecure: boolean
}

export function resolveHost(opts: ResolveHostOptions): string {
  let raw = opts.raw.trim()
  if (raw === '') raw = DEFAULT_HOST
  if (!raw.includes('://')) raw = `https://${raw}`
  let url: URL
  try {
    url = new URL(raw)
  } catch (err) {
    throw new BaseError({
      code: ErrorCode.UsageInvalidFlag,
      message: `host parse: ${(err as Error).message}`,
    })
  }
  url.pathname = url.pathname.replace(/\/+$/, '')
  if (url.protocol !== 'https:' && !(opts.insecure && url.protocol === 'http:')) {
    throw new BaseError({
      code: ErrorCode.UsageInvalidFlag,
      message: 'only https:// hosts are accepted',
      hint: 'add --insecure to allow http:// (local-dev only; user_code/device_code travel plaintext)',
    })
  }
  const out = url.toString()
  return out.endsWith('/') ? out.slice(0, -1) : out
}

export function hostWithScheme(host: string, scheme: string | undefined): string {
  if (host.includes('://')) return host

View on GitHub (pinned to ef8544b173)

Solutions

  1. Pass a clean host: `--host cloud.dify.ai` or `--host https://cloud.dify.ai` (no path, no spaces).
  2. Shell-quote values containing special characters, and prefer to avoid embedded spaces in hostnames entirely.
  3. Strip trailing slashes and paths — resolveHost normalizes the pathname but the host itself should be just scheme://host[:port].
  4. If your host genuinely needs an unusual character, percent-encode it per RFC 3986.

Example fix

# before
export DIFY_HOST='cloud dify ai'
difyctl --host "$DIFY_HOST" apps list   # URL parse fails on the space

# after
export DIFY_HOST='cloud.dify.ai'
difyctl --host "$DIFY_HOST" apps list
Defensive patterns

Strategy: validation

Validate before calling

// validate the host string the same way resolveHost does, before calling the command
function preValidateHost(raw: string): URL {
  let s = raw.trim()
  if (s === '') s = 'https://cloud.dify.ai'
  if (!s.includes('://')) s = `https://${s}`
  try {
    return new URL(s)
  } catch (err) {
    throw new Error(`host parse: ${(err as Error).message}`)
  }
}

Type guard

function isParsableHost(raw: string): boolean {
  try {
    let s = raw.trim()
    if (s === '') return true
    if (!s.includes('://')) s = `https://${s}`
    new URL(s)
    return true
  } catch {
    return false
  }
}

Prevention

When it happens

Trigger: `--host 'cloud dify ai'` (spaces), `--host 'https://cloud.dify.ai/space path'` (space in path before scheme-stripping — though URL may tolerate some of these), `--host '%zz'` (bad percent-encoding), or a value with control characters. Most plain hostname typos get rescued by the `https://` prepend and parse fine, then possibly fail DNS later.

Common situations: Copy-pasting a host with a trailing path that includes characters URL rejects; shell quoting that let a space in; env var with stray characters; a host string that includes credentials with special chars ('@', ':') confusing the URL parser into a malformed authority.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/ed8b87c9415736c8. Report an issue: GitHub.