deepseek-ai/deepseek-harness · error · TypertGatewayError

lookup-failed

lookup-failed

Error message

lookup provider ${JSON.stringify(key)} failed

What it means

The lookup provider's resolve(value) rejected with an exception other than TypertLookupFailure (which passes through with its own failure identity). The Gateway wraps it as lookup-failed with the original error as cause and the parameter's wire field as field: an infrastructure failure while turning the wire id into the Host object, not an invalid request.

Source

Thrown at packages/api/gateway/src/index.ts:452

        `lookup provider ${JSON.stringify(key)} is unavailable`,
        { field: parameter.wire },
      )
    }
    if (provider.wire !== parameter.wire
      || (parameter.codec.mode === 'strict' && provider.wireTypeSymbol !== parameter.codec.typeSymbol)) {
      throw new TypertGatewayError(
        'provider-mismatch',
        endpoint,
        `lookup provider ${JSON.stringify(key)} does not match its strict definition`,
        { field: parameter.wire },
      )
    }
    let resolved: unknown
    try {
      resolved = await provider.resolve(value)
    } catch (cause) {
      if (cause instanceof TypertLookupFailure) throw cause
      throw new TypertGatewayError(
        'lookup-failed',
        endpoint,
        `lookup provider ${JSON.stringify(key)} failed`,
        { cause, field: parameter.wire },
      )
    }
    if (resolved === undefined) {
      throw new TypertGatewayError(
        'lookup-not-found',
        endpoint,
        `lookup provider ${JSON.stringify(key)} did not resolve the requested identity`,
        { field: parameter.wire },
      )
    }
    return resolved
  }
}

View on GitHub (pinned to b150a551b8)

Solutions

  1. Read error.cause and fix the underlying provider failure (restore the store, correct the bug).
  2. Return undefined from the resolver for ids that simply do not exist, so they map to lookup-not-found instead of lookup-failed.
  3. Once the backing service is healthy again, retry the original invoke.

Example fix

// before — resolver throws on unknown ids, surfacing infrastructure failures for normal misses
async resolve(id: string) {
  return await docs.get(id) // docs.get throws NotFoundError
}
// after — misses return undefined (→ lookup-not-found); only real failures throw
async resolve(id: string) {
  const doc = await docs.get(id).catch(cause => {
    if (cause instanceof NotFoundError) return null
    throw cause
  })
  return doc ?? undefined
}
Defensive patterns

Strategy: try-catch

Type guard

import { TypertGatewayError } from '@deepseek-ai/dsh-api-gateway'

function isLookupFailed(error: unknown): error is TypertGatewayError {
  return error instanceof TypertGatewayError && error.code === 'lookup-failed'
}

Try / catch

try {
  await gateway.invoke(request)
} catch (error) {
  if (error instanceof TypertGatewayError && error.code === 'lookup-failed') {
    // classify as a 5xx-side dependency failure with the cause chain; never a client 4xx
    logger.error('lookup provider failure', { field: error.field, cause: error.cause })
    throw error
  }
  throw error
}

Prevention

When it happens

Trigger: A lookup resolver hitting its backing store and rejecting (database down, file system error, network timeout to an external service), or resolver code throwing on unexpected state, while resolveParameter resolves a source 'lookup' argument.

Common situations: Backing-store outage behind the lookup; a resolver throwing TypeError on a value that passed wire validation but breaks internal assumptions; transient failures in an external dependency.

Related errors


AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24). Data as JSON: /api/errors/76c576830c3f7e80. Report an issue: GitHub.