{"record":{"id":"fd35c74889013669","repo":"hcengineering/platform","slug":"badrequest-fd35c7","errorCode":"BadRequest","errorMessage":"BadRequest","messagePattern":"BadRequest","errorType":"exception","errorClass":"PlatformError","httpStatus":null,"severity":"warning","filePath":"server/account/src/serviceOperations.ts","lineNumber":320,"sourceCode":"  branding: Branding | null,\n  token: string,\n  params: {\n    workspaceUuid: WorkspaceUuid\n    event: WorkspaceEvent\n    version: Data<Version> // A worker version\n    progress: number\n    message?: string\n  }\n): Promise<void> {\n  const { workspaceUuid, event, version, message } = params\n\n  const { extra } = decodeTokenVerbose(ctx, token)\n  if (!['workspace', 'tool'].includes(extra?.service)) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))\n  }\n\n  if (workspaceUuid == null || workspaceUuid === '' || event == null) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))\n  }\n\n  let progress = params.progress\n\n  const wsExists = await db.workspace.exists({ uuid: workspaceUuid })\n  if (!wsExists) {\n    throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, { workspaceUuid }))\n  }\n  progress = Math.round(progress)\n\n  const ts = Date.now()\n  const update: Partial<WorkspaceStatus> = {}\n  const wsUpdate: Partial<Workspace> = {}\n  const query: Query<WorkspaceStatus> = { workspaceUuid }\n\n  // Only read status for certain events because it is not needed for others\n  // and it interferes with status updates when concurrency is high\n  let wsStatus: WorkspaceStatus | null = null","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server/account/src/serviceOperations.ts#L302-L338","documentation":"BadRequest is thrown by updateWorkspaceInfo when required parameters are missing or empty: workspaceUuid is null/empty string, or event is null. This check runs after the service-allowlist check, so the caller is authorized but sent an incomplete payload. It signals malformed request data rather than an auth or state problem.","triggerScenarios":"Passing workspaceUuid as '' or undefined, or omitting the event field, when calling updateWorkspaceInfo — e.g. an uninitialized workspace record ID, a variable not yet assigned, or an event enum/value that failed to serialize.","commonSituations":"Callers constructing the params object dynamically and skipping empty workspaceUuid; race where a workspace-create hasn't returned an ID yet; TypeScript strict mode off letting undefined through; event produced by a mapping function returning null on unknown workspace states.","solutions":["Validate workspaceUuid is a non-empty UUID string and event is non-null before calling updateWorkspaceInfo.","Ensure the workspace was created and its UUID was received (await the create call) before sending status updates.","Check serialization of the params object (no dropped fields from spread/JSON transforms).","Return/log a clear client-side error instead of calling the API with incomplete data."],"exampleFix":"// before\nawait accountClient.updateWorkspaceInfo(ctx, token, { workspaceUuid: wsId, event })\n\n// after\nif (!wsId || event == null) {\n  throw new Error(`updateWorkspaceInfo requires workspaceUuid and event, got wsId=${wsId}, event=${event}`)\n}\nawait accountClient.updateWorkspaceInfo(ctx, token, { workspaceUuid: wsId, event })","handlingStrategy":"validation","validationCode":"// Validate required params before the API call\nif (workspaceUuid == null || workspaceUuid === '') {\n  throw new Error('workspaceUuid must be a non-empty UUID')\n}\nif (event == null) {\n  throw new Error('event is required for updateWorkspaceInfo')\n}","typeGuard":"function isValidUpdatePayload(p: UpdateWorkspaceInfoParams): p is UpdateWorkspaceInfoParams & { workspaceUuid: string; event: WorkspaceEvent } {\n  return p.workspaceUuid != null && p.workspaceUuid !== '' && p.event != null\n}","tryCatchPattern":"try {\n  await updateWorkspaceInfo(ctx, token, params)\n} catch (err) {\n  if (err instanceof PlatformError && err.status.code === platform.status.BadRequest) {\n    log.error('updateWorkspaceInfo payload incomplete', { params })\n    return\n  }\n  throw err\n}","preventionTips":["Enable TypeScript strict null checks so missing fields fail at compile time.","Always await workspace creation and use the returned UUID before sending updates.","Add a schema validator (e.g. zod) on params before calling internal APIs.","Log the full payload when constructing requests to catch dropped fields early."],"tags":["validation","bad-request","parameters","workspace"],"backgroundTag":"missing-required-parameter","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}