langgenius/dify · error · BaseError

usage_missing_arg

usage_missing_arg

Error message

--host is required (no TTY)

What it means

Raised by PipelineTemplateDetailApi.get (GET /rag/pipeline/templates/{template_id}) when RagPipelineService.get_pipeline_template_detail returns None. The detail lookup is delegated to an upstream service (built-in template registry or customized-template store) keyed by template_id and req_data.type. A None result means the template_id is unknown for the requested type. Maps to HTTP 404.

Source

Thrown at cli/src/commands/auth/login/login.ts:108

  await storeBundle.store.write(display, email, success.token)

  const reg = await Registry.load()
  reg.token_storage = storeBundle.mode
  reg.activate(display, email, ctx)
  applyScheme(reg, display, host)
  reg.setInsecureTls(display, insecure)
  await reg.save()

  renderLoggedIn(opts.io.out, cs, host, success)
  return reg
}

async function resolveLoginHost(opts: LoginOptions, insecure: boolean): Promise<string> {
  const raw = opts.host?.trim() ?? ''
  if (raw !== '') return resolveHost({ raw, insecure })
  if (!opts.io.isErrTTY) {
    throw new BaseError({
      code: ErrorCode.UsageMissingArg,
      message: '--host is required (no TTY)',
      hint: "pass the host explicitly, e.g. 'difyctl auth login --host cloud.dify.ai'",
    })
  }
  return promptHost(opts.io, insecure)
}

function makeHostParser(insecure: boolean): (raw: string) => ParseResult<string> {
  return (raw: string) => {
    try {
      return { ok: true, value: resolveHost({ raw, insecure }) }
    } catch (err) {
      if (isBaseError(err)) {
        const msg = err.hint !== undefined ? `${err.message} — ${err.hint}` : err.message
        return { ok: false, error: msg }
      }
      return { ok: false, error: String(err) }

View on GitHub (pinned to ef8544b173)

Solutions

  1. List templates first via GET /rag/pipeline/templates?type={type} and use an id returned by that call.
  2. Retry once after a short delay to rule out a transient upstream empty response.
  3. If the template was deleted upstream, pick a current built-in template or restore the customized template.

Example fix

// before
const detail = await get(`/rag/pipeline/templates/${id}?type=built-in`);
// after
const list = await get(`/rag/pipeline/templates?type=built-in`).then(r => r.json());
const id = list.pipeline_templates[0].id;  // use a known-good id
const detail = await get(`/rag/pipeline/templates/${id}?type=built-in`);
Defensive patterns

Strategy: validation

Validate before calling

async function templateExists(client, templateId: string, type: 'built-in' | 'customized'): Promise<boolean> {
  const r = await client.get(`/console/api/rag/pipeline/templates?type=${type}`);
  const list = await r.json();
  return Array.isArray(list.pipeline_templates) && list.pipeline_templates.some(t => t.id === templateId);
}

Type guard

function isKnownTemplateId(id: string, known: Set<string>): boolean { return known.has(id); }

Try / catch

try {
  return await client.get(`/rag/pipeline/templates/${templateId}?type=${type}`);
} catch (e) {
  if (e.response?.status === 404) {
    await refreshTemplateList(type);  // could also be a transient upstream empty
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /console/api/rag/pipeline/templates/{template_id}?type=built-in where template_id is not in the upstream built-in catalog; or ?type=customized where the tenant has no customized template with that id; upstream template service temporarily returned empty due to a fetch failure parsed as None.

Common situations: Template was removed upstream in a newer Dify version; client cached a template_id from a previous version; customized template was deleted by another tenant member; network/upstream blip returned an empty body that the service coerced to None.

Related errors


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