hcengineering/platform · error · HttpError

Missing workspace

Error message

Missing workspace

What it means

withBlob reads req.params.workspace and req.params.name and throws HttpError 400 'Missing workspace' when the workspace param is undefined or empty. It is a request-shape validation guard before blob access.

Source

Thrown at pods/preview/src/middleware.ts:80

    next()
  } catch (err: any) {
    next(err)
  }
}

/**
 * Validates blob route params and ensures the caller's token grants access to
 * the workspace taken from the URL. Must run after `withAuthorization`, which
 * guarantees a token is present.
 */
export const withBlob = (req: RequestWithAuth, res: Response, next: NextFunction): void => {
  try {
    const workspace = req.params.workspace
    const name = req.params.name

    if (workspace === undefined || workspace === '') {
      throw new HttpError(400, 'Missing workspace')
    }
    if (name === undefined || name === '') {
      throw new HttpError(400, 'Missing blob name')
    }

    const token = req.token
    if (token == null) {
      throw new HttpError(401, 'Unauthorized')
    }

    const hasWorkspaceAccess =
      (token.workspace as string) === workspace || token.account === systemAccountUuid || token.extra?.admin === 'true'
    if (!hasWorkspaceAccess) {
      throw new HttpError(401, 'Unauthorized')
    }

    next()
  } catch (err: any) {

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Include the workspace name in the URL path (e.g. /blob/{workspace}/{name})
  2. Ensure the route registration matches the client's URL shape so params populate
  3. Guard on the client: encodeURIComponent(workspace) before building the URL
  4. Check for empty-string interpolation when workspace is dynamic

Example fix

// before
fetch(`/blob/${workspace}/logo.png`)
// after
if (!workspace) throw new Error('workspace is required')
fetch(`/blob/${encodeURIComponent(workspace)}/logo.png`)
Defensive patterns

Strategy: validation

Validate before calling

function blobUrl (workspace: string, name: string): string {
  if (!workspace) throw new Error('workspace is required')
  if (!name) throw new Error('blob name is required')
  return `/blob/${encodeURIComponent(workspace)}/${encodeURIComponent(name)}`
}

Type guard

function isNonEmptyString (v: unknown): v is string {
  return typeof v === 'string' && v.length > 0
}

Try / catch

try {
  const res = await fetch(blobUrl(ws, name), { headers: authHeaders() })
  if (res.status === 400) {
    // bad request shape: verify workspace/name params
  }
} catch (err) { /* handle */ }

Prevention

When it happens

Trigger: Hitting a blob endpoint without a :workspace route parameter, or with workspace='' (empty segment).

Common situations: Client URL template missing the workspace segment (e.g. /blob//name); router path misconfigured so params aren't bound; programmatic fetch building URL with undefined interpolated.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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