{"record":{"id":"6c6840cd4077cace","repo":"aeron-io/aeron","slug":"livestreamid-must-be-set","errorCode":null,"errorMessage":"liveStreamId must be set","messagePattern":"liveStreamId must be set","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java","lineNumber":1687,"sourceCode":"        /**\n         * Conclude configuration by setting up defaults when specifics are not provided.\n         */\n        @SuppressWarnings(\"MethodLength\")\n        public void conclude()\n        {\n            if ((boolean)IS_CONCLUDED_VH.getAndSet(this, true))\n            {\n                throw new ConcurrentConcludeException();\n            }\n\n            if (Aeron.NULL_VALUE == recordingId)\n            {\n                throw new ConfigurationException(\"recordingId must be set\");\n            }\n\n            if (Aeron.NULL_VALUE == liveStreamId)\n            {\n                throw new ConfigurationException(\"liveStreamId must be set\");\n            }\n\n            if (Strings.isEmpty(liveChannel))\n            {\n                throw new ConfigurationException(\"liveChannel must be set\");\n            }\n\n            if (Strings.isEmpty(replayChannel))\n            {\n                throw new ConfigurationException(\"replayChannel must be set\");\n            }\n\n            if (Aeron.NULL_VALUE == replayStreamId)\n            {\n                throw new ConfigurationException(\"replayStreamId must be set\");\n            }\n\n            if (null == aeronArchiveContext)","sourceCodeStart":1669,"sourceCodeEnd":1705,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java#L1669-L1705","documentation":"PersistentSubscription.Builder.conclude() validates that liveStreamId was set and throws ConfigurationException(\"liveStreamId must be set\") when it equals Aeron.NULL_VALUE. A persistent subscription needs the live stream id to follow the live stream once the recording's replay catches up.","triggerScenarios":"conclude() invoked on a builder where liveStreamId() was never called or set to Aeron.NULL_VALUE — recordingId and liveChannel may be fine, but the live follow stream id is missing.","commonSituations":"Builders configured from partial config files where only channel was provided and streamId was omitted; assuming liveStreamId has a default; copying builder setup code and dropping the liveStreamId line.","solutions":["Call builder.liveStreamId(streamId) with a valid stream id before conclude()","Wire the same streamId used for the recording into the persistent subscription builder","Validate config/CLI inputs so a missing stream id fails at parse time, not at conclude()","Check builder call order — ensure no early return skips liveStreamId(...) setup"],"exampleFix":"// before\nb.recordingId(recordingId).liveChannel(liveChannel);\nb.conclude(); // liveStreamId missing\n\n// after\nb.recordingId(recordingId).liveChannel(liveChannel).liveStreamId(streamId);\nb.conclude();","handlingStrategy":"validation","validationCode":"if (liveStreamId == Aeron.NULL_VALUE) {\n    throw new IllegalArgumentException(\"liveStreamId must be resolved before building PersistentSubscription\");\n}","typeGuard":"boolean hasLiveStreamId(int streamId) { return streamId != Aeron.NULL_VALUE; }","tryCatchPattern":"try {\n    builder.conclude();\n} catch (ConfigurationException e) {\n    if (e.getMessage().equals(\"liveStreamId must be set\")) {\n        throw new IllegalStateException(\"liveStreamId is required for a persistent subscription\", e);\n    }\n}","preventionTips":["Set every required builder field (recordingId, liveChannel, liveStreamId) in one helper so none is skipped","Require streamId in configuration parsing rather than defaulting it","Call conclude() only after all setters are verified","Reuse the same stream id constants for recording and live follow"],"tags":["configuration","validation","required-field","aeron-archive"],"backgroundTag":"missing-required-config-field","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}