{"record":{"id":"c4cb974eca6259ac","repo":"ruvnet/ruflo","slug":"rollout-rolloutid-not-found","errorCode":null,"errorMessage":"Rollout ${rolloutId} not found","messagePattern":"Rollout (.+?) not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/plugin-iot-cognitum/src/domain/services/firmware-orchestration-service.ts","lineNumber":217,"sourceCode":"  private async deployToDevices(\n    rollout: FirmwareRollout,\n    deviceIds: string[],\n    version: string,\n  ): Promise<void> {\n    for (const deviceId of deviceIds) {\n      const result = await this.deps.deployFirmware(deviceId, version);\n      if (result.success) {\n        rollout.completedDeviceIds.push(deviceId);\n      } else {\n        rollout.failedDeviceIds.push(deviceId);\n      }\n    }\n  }\n\n  private getExistingRollout(rolloutId: string): FirmwareRollout {\n    const rollout = this.rollouts.get(rolloutId);\n    if (!rollout) {\n      throw new Error(`Rollout ${rolloutId} not found`);\n    }\n    return rollout;\n  }\n}\n","sourceCodeStart":199,"sourceCodeEnd":222,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/plugin-iot-cognitum/src/domain/services/firmware-orchestration-service.ts#L199-L222","documentation":"FirmwareOrchestrationService keeps rollouts in an in-memory map; getExistingRollout() throws for any follow-up operation whose rolloutId is not in that map. The ID must have been created by this same service instance within its lifetime.","triggerScenarios":"Referencing a rollout ID created before a service restart, by another process or replica, or a mistyped ID; or the createRollout call failed so no entry exists under that ID.","commonSituations":"Long-running fleet campaigns that span deploys (the restart loses the map); horizontally scaled coordinators where the rollout lives on a different instance; rollout IDs copied between environments.","solutions":["Use the rollout ID returned by the same service instance that created it, within that instance's lifetime","Re-create the rollout after a restart instead of reusing the old ID","Persist rollout IDs externally if follow-up operations must survive restarts"],"exampleFix":"// before\nawait fwService.advanceRollout(rolloutIdFromLastDeploy); // map empty after restart -> throws\n\n// after\nconst { rolloutId } = await fwService.createRollout(spec); // fresh, same instance\nawait fwService.advanceRollout(rolloutId);","handlingStrategy":"validation","validationCode":"const active = new Set<string>(); // rolloutIds created by THIS service instance\nconst { rolloutId } = await fwService.createRollout(spec);\nactive.add(rolloutId);\nif (!active.has(rolloutId)) throw new Error('rollout not created here; refusing follow-up');\nawait fwService.advanceRollout(rolloutId);","typeGuard":null,"tryCatchPattern":"try {\n  await fwService.advanceRollout(rolloutId);\n} catch (e) {\n  if (e instanceof Error && e.message.endsWith('not found')) {\n    // rollout map lost (restart or other instance): re-create the rollout from spec\n  } else throw e;\n}","preventionTips":["Treat rollouts as session-scoped state; recreate rather than resume across restarts","Keep the creating call and follow-up calls on the same coordinator instance","Store rollout IDs together with the identity of the instance that created them"],"tags":["iot","firmware-update","entity-not-found","in-memory-state"],"backgroundTag":"entity-not-found","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}