{"record":{"id":"a78370cdc521f732","repo":"hcengineering/platform","slug":"process-error-emptyfunctionresult","errorCode":"process.error.EmptyFunctionResult","errorMessage":"Empty function result {func}","messagePattern":"Empty function result (.+?)","errorType":"exception","errorClass":"ProcessError","httpStatus":null,"severity":"error","filePath":"server-plugins/process-resources/src/utils.ts","lineNumber":268,"sourceCode":"  const func = control.client.getModel().findObject(context.func)\n  if (func === undefined) throw processError(process.error.MethodNotFound, { methodId: context.func }, {}, true)\n  const impl = control.client.getHierarchy().as(func, serverProcess.mixin.FuncImpl)\n  if (impl === undefined) throw processError(process.error.MethodNotFound, { methodId: context.func }, {}, true)\n  const f = await getResource(impl.func)\n  const res = await f(null, context.props, control, execution)\n  if (context.sourceFunction !== undefined) {\n    const transform = control.client.getModel().findObject(context.sourceFunction.func)\n    if (transform === undefined) {\n      throw processError(process.error.MethodNotFound, { methodId: context.sourceFunction.func }, {}, true)\n    }\n    if (!control.client.getHierarchy().hasMixin(transform, serverProcess.mixin.FuncImpl)) {\n      throw processError(process.error.MethodNotFound, { methodId: context.sourceFunction.func }, {}, true)\n    }\n    const funcImpl = control.client.getHierarchy().as(transform, serverProcess.mixin.FuncImpl)\n    const f = await getResource(funcImpl.func)\n    const val = await f(res, {}, control, execution)\n    if (val == null && context.func !== process.function.EmptyValue) {\n      throw processError(process.error.EmptyFunctionResult, {}, { func: func.label })\n    }\n    return val\n  }\n  if (res == null && context.func !== process.function.EmptyValue) {\n    throw processError(process.error.EmptyFunctionResult, {}, { func: func.label })\n  }\n  return res\n}\n\nfunction getUserRequestValue (control: ProcessControl, execution: Execution, context: SelectedUserRequest): any {\n  const userContext = execution.context[context.id]\n  if (userContext !== undefined) return userContext\n  const attr = control.client.getHierarchy().findAttribute(context._class, context.key)\n  throw processError(\n    process.error.UserRequestedValueNotProvided,\n    {},\n    { attr: attr?.label ?? getEmbeddedLabel(context.key) }\n  )","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server-plugins/process-resources/src/utils.ts#L250-L286","documentation":"Thrown when the transform function (sourceFunction) returns null/undefined and the primary function is not process.function.EmptyValue (which legitimately allows empty results). A required function chain produced no value.","triggerScenarios":"val = await f(res, {}, control, execution) yields null while context.func !== EmptyValue — the transform filtered out all input or returned nothing for the given input.","commonSituations":"Transform's filter predicate matches nothing; upstream primary function returned data the transform does not handle; logic bug returning null instead of a default.","solutions":["Fix the transform to return a valid value or a sensible default","Check the primary function's output matches what the transform expects","Use process.function.EmptyValue as context.func if empty results are acceptable","Add logging in the transform to see the input res and returned val"],"exampleFix":"// before\nconst val = await f(res, {}, control, execution)\n// after\nconst val = await f(res, {}, control, execution) ?? [] // explicit default instead of null","handlingStrategy":"try-catch","validationCode":"const val = await transformFn(res, {}, control, execution)\nif (val == null) {\n  throw new Error(`transform returned no value for input ${JSON.stringify(res)}`)\n}","typeGuard":"function isDefined<T>(v: T | null | undefined): v is T { return v !== null && v !== undefined }","tryCatchPattern":"try {\n  val = await getContextValue(control, execution, context)\n} catch (e) {\n  if (e?.code === 'process.error.EmptyFunctionResult') {\n    val = [] // or surface a user-facing 'no data' state\n  } else throw e\n}","preventionTips":["Return defaults instead of null from transform functions","Use process.function.EmptyValue when empty results are valid","Log transform inputs/outputs during development to spot null paths"],"tags":["process","null-value","function-result","transform"],"backgroundTag":"empty-function-result","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}