hcengineering/platform · error

Bad Request

Error message

Bad Request

What it means

The /details endpoint of the link-preview server requires a query string. If req.query is undefined entirely, the handler short-circuits with HTTP 400 and { message: 'Bad Request' }. This guards downstream code from dereferencing req.query.

Source

Thrown at pods/link-preview/src/server.ts:88

      requests.info(text)
    }
  }

  const wrapRequest =
    (ctx: MeasureContext, name: string, fn: AsyncRequestHandler) =>
      (req: RequestWithAuth, res: Response, next: NextFunction) => {
      // eslint-disable-next-line @typescript-eslint/no-floating-promises
        handleRequest(ctx, name, fn, req, res, next)
      }

  app.use(morgan('short', { stream: new LogStream() }))

  app.get(
    '/details',
    withAuthorization,
    wrapRequest(ctx, 'getLinkPreviewDetails', async (ctx, req, res) => {
      if (req.query === undefined) {
        res.status(400).json({ message: 'Bad Request' })
        return
      }
      if (req.query.q === undefined) {
        res.status(400).json({ message: 'Bad Request' })
        return
      }
      const url = req.query.q as string
      try {
        const result = await parseLinkPreviewDetails(ctx, config, url)
        res.status(200).json(result)
      } catch (err) {
        console.error({ message: 'failed to parse link preview details', url, err })
        res.status(422).json({ message: 'Unprocessable Entity' })
      }
    })
  )

  app.get('/api/v1/statistics', (req, res) => {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Include a query string on the request, e.g. GET /details?q=https%3A%2F%2Fexample.com
  2. URL-encode the target URL value of q
  3. Check intermediaries (proxies, redirects) are not stripping the query string
  4. Fix client code to always append at least one query parameter when calling /details

Example fix

// before
fetch(`${base}/details`)
// after
const url = new URL(`${base}/details`)
url.searchParams.set('q', targetUrl)
fetch(url) // /details?q=https%3A%2F%2Fexample.com
Defensive patterns

Strategy: validation

Validate before calling

function buildDetailsUrl(base: string, target: string): string {
  if (!target) throw new Error('target url required')
  const u = new URL(`${base}/details`)
  u.searchParams.set('q', target)
  return u.toString()
}

Type guard

null

Try / catch

const res = await fetch(url)
if (res.status === 400) {
  throw new Error('request must include a query string: /details?q=<encoded url>')
}

Prevention

When it happens

Trigger: Calling GET /details with no query string at all (e.g. curl without any parameters, or a client that dropped the query when building the URL).

Common situations: Hand-built requests missing '?q=...'; proxy/gateway stripping the query string; client HTTP libraries that require explicit query construction; tests hitting the bare endpoint path.

Related errors


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