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.

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.

Appendix: 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)