{"record":{"id":"705b90522b4e764d","repo":"aeron-io/aeron","slug":"recordingid-must-be-set","errorCode":null,"errorMessage":"recordingId must be set","messagePattern":"recordingId must be set","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java","lineNumber":1682,"sourceCode":"            {\n                throw new RuntimeException(ex);\n            }\n        }\n\n        /**\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)","sourceCodeStart":1664,"sourceCodeEnd":1700,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java#L1664-L1700","documentation":"PersistentSubscription.Builder.conclude() validates required fields and throws ConfigurationException(\"recordingId must be set\") when recordingId is still Aeron.NULL_VALUE. A persistent subscription cannot be created without knowing which recording it consumes.","triggerScenarios":"Calling conclude() on a PersistentSubscription.Builder whose recordingId() was never called (or was set to Aeron.NULL_VALUE, e.g. from an unset/failed replay-destination lookup).","commonSituations":"Configuration code that conditionally sets recordingId but the condition failed silently; parsing a recording id from config/args returned null/default; initializing the subscription before the recording was actually started and its id obtained.","solutions":["Call builder.recordingId(id) with a valid (non-NULL_VALUE) recording id before conclude()","Obtain the recording id from AeronArchive.listRecording/listRecordingsForUri before building the subscription","Validate configuration/arguments that supply the recording id early with a clear failure","Start the recording first, capture the returned recordingId, then construct the persistent subscription"],"exampleFix":"// before\nPersistentSubscription.Builder b = new PersistentSubscription.Builder();\nb.conclude(); // recordingId never set\n\n// after\nlong recordingId = aeronArchive.startRecording(channel, streamId, LOCAL);\nb.recordingId(recordingId).liveChannel(liveChannel).liveStreamId(streamId);\nb.conclude();","handlingStrategy":"validation","validationCode":"if (recordingId == Aeron.NULL_VALUE) {\n    throw new IllegalArgumentException(\"recordingId must be resolved before building PersistentSubscription\");\n}","typeGuard":"boolean hasRecordingId(PersistentSubscription.Builder b) { return recordingId != Aeron.NULL_VALUE; }","tryCatchPattern":"try {\n    builder.conclude();\n} catch (ConfigurationException e) {\n    if (e.getMessage().equals(\"recordingId must be set\")) {\n        throw new IllegalStateException(\"resolve recording id via AeronArchive before subscribing\", e);\n    }\n}","preventionTips":["Always fetch the recording id (startRecording/listRecordingsForUri) before building the subscription","Fail fast when config/args yield a null/default recording id","Use long primitives (not boxed Long) to avoid accidental NULL_VALUE defaults","Add an assert on recordingId != Aeron.NULL_VALUE in setup code"],"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-16T04:17:20.429Z"}