hcengineering/platform · error · PlatformError

unknownError(response.statusText)

Error message

unknownError(response.statusText)

What it means

In searchFulltext, if the HTTP response is not ok (and is not a 429 rate limit, which is handled first), the client throws a PlatformError built via unknownError(response.statusText). It represents an unexpected HTTP failure during a full-text search whose exact cause is only captured in the status/statusText.

Source

Thrown at foundations/core/packages/api-client/src/rest/rest.ts:300

      params.append('query', query.query)
      if (query.classes != null && Object.keys(query.classes).length > 0) {
        params.append('classes', JSON.stringify(query.classes))
      }
      if (query.spaces != null && Object.keys(query.spaces).length > 0) {
        params.append('spaces', JSON.stringify(query.spaces))
      }
      if (options.limit != null) {
        params.append('limit', `${options.limit}`)
      }
      const requestUrl = concatLink(this.endpoint, `/api/v1/search-fulltext/${this.workspace}?${params.toString()}`)
      const response = await fetch(requestUrl, {
        method: 'GET',
        headers: this.jsonHeaders(),
        keepalive: true
      })
      if (!response.ok) {
        await this.checkRateLimits(response)
        throw new PlatformError(unknownError(response.statusText))
      }
      this.updateRateLimit(response)
      return await extractJson<TxResult>(response)
    })
    if (result.error !== undefined) {
      throw new PlatformError(result.error)
    }
    return result
  }

  async domainRequest<T>(
    domain: OperationDomain,
    params: DomainParams,
    options?: DomainRequestOptions
  ): Promise<DomainResult<T>> {
    const requestUrl = concatLink(this.endpoint, `/api/v1/request/${domain}/${this.workspace}`)

    await this.checkRate()

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Log response.statusText/status in a catch around searchFulltext and map 401 to re-authentication.
  2. Refresh the token if the status is 401 and retry once.
  3. Verify the workspace and query are valid and the user has access.
  4. Retry with backoff for 5xx/502/504; check server health/logs for persistent 500s.

Example fix

// before
const res = await client.searchFulltext(query, {})
// after
let res
try { res = await client.searchFulltext(query, {}) }
catch (e) {
  if (e instanceof PlatformError && /unauthorized/i.test(e.message)) { await reconnect(); res = await client.searchFulltext(query, {}) }
  else throw e
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof query !== 'string' || query.trim() === '') throw new Error('searchFulltext requires a non-empty query')
// also ensure the client was created with a valid, unexpired token

Type guard

function isPlatformError(e: unknown): e is PlatformError {
  return e instanceof PlatformError
}

Try / catch

try {
  return await client.searchFulltext(query, {})
} catch (e) {
  if (isPlatformError(e)) {
    if (/unauthorized|401/i.test(e.message)) { await refreshToken(); return client.searchFulltext(query, {}) }
    if (/50[0234]/.test(e.message)) { await sleep(2000); return client.searchFulltext(query, {}) }
  }
  throw e
}

Prevention

When it happens

Trigger: searchFulltext receiving a 4xx/5xx response (401 unauthorized token, 403 forbidden, 500 server error, 502/504 from a proxy) from the search endpoint.

Common situations: Expired or invalid token (401), missing permissions on the workspace (403), search/transactor service crash or restart (500), gateway timeouts under heavy load, server version mismatch altering the endpoint.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/853598085106d785. Report an issue: GitHub.