langgenius/dify · error · BaseError

usage_missing_arg

usage_missing_arg

Error message

device_label is required

What it means

Raised by DatasetsHitTestingBase.perform_hit_testing when the response dict from HitTestingService.retrieve has a 'query' field that is not a dict, or whose 'content' entry is not a string. This guards the retrieval-service contract before the controller reshapes the response. It is an internal server error surfaced as ValueError and ultimately HTTP 500 via the catch-all except clause.

Source

Thrown at cli/src/api/oauth-device.ts:73

  | { status: 'approved'; success: PollSuccess }

const POLL_ERROR_TO_STATUS: Record<string, PollResult['status']> = {
  authorization_pending: 'pending',
  slow_down: 'slow_down',
  expired_token: 'expired',
  access_denied: 'denied',
}

export class DeviceFlowApi {
  private readonly http: HttpClient

  constructor(http: HttpClient) {
    this.http = http
  }

  async requestCode(req: CodeRequest): Promise<CodeResponse> {
    if (req.device_label === '') {
      throw new BaseError({
        code: ErrorCode.UsageMissingArg,
        message: 'device_label is required',
      })
    }
    const body = { client_id: req.client_id ?? DEFAULT_CLIENT_ID, device_label: req.device_label }
    const res = await this.http.fetch('oauth/device/code', { method: 'POST', json: body })
    if (res.status === 404) throw versionSkew()
    if (!res.ok) {
      throw new HttpClientError({
        code: ErrorCode.Server4xxOther,
        message: `device/code: HTTP ${res.status}`,
        httpStatus: res.status,
      })
    }
    return (await res.json()) as CodeResponse
  }

  async pollOnce(req: PollRequest): Promise<PollResult> {

View on GitHub (pinned to ef8544b173)

Solutions

  1. Check server logs (logger.exception logs the full traceback) to see the actual shape returned by HitTestingService.retrieve.
  2. Fix the retrieval implementation to always return {'query': {'content': <str>}, 'records': [...]} .
  3. Add an integration test asserting retrieve returns the documented contract.

Example fix

# before
return {"records": retrieved_records}
# after
return {"query": {"content": query_text}, "records": retrieved_records}
Defensive patterns

Strategy: type-guard

Validate before calling

from typing import Any, cast

def validate_retrieve_response(response: Any) -> dict:
    if not isinstance(response, dict):
        raise TypeError('retrieve must return a dict')
    q = response.get('query')
    if not isinstance(q, dict) or not isinstance(q.get('content'), str):
        raise TypeError('retrieve response.query must be {content: str}')
    return response
# call in HitTestingService.retrieve before returning

Type guard

from typing import Any

def is_query_echo(value: Any) -> bool:
    return isinstance(value, dict) and isinstance(value.get('content'), str)

Try / catch

try:
    response = HitTestingService.retrieve(...)
except Exception:
    logger.exception('retrieve failed')
    raise InternalServerError('hit testing failed')
# Note: the malformed-shape ValueError is a server bug; not retryable.

Prevention

When it happens

Trigger: HitTestingService.retrieve returns a dict missing the 'query' key, returns query as None or a string, or returns query.content as a non-string (e.g. a dict). Happens after a retrieval-backend regression or a partial failure that returned an empty/malformed response.

Common situations: A new retrieval mode forgot to populate the query echo; an external knowledge adapter returned only records without echoing the query; a refactor changed the retrieve return type without updating this contract check.

Related errors


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