{"record":{"id":"b13ce3e9f5753568","repo":"alibaba/spring-ai-alibaba","slug":"thread-id-is-null","errorCode":null,"errorMessage":"Thread id is null","messagePattern":"Thread id is null","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-studio/src/main/java/com/alibaba/cloud/ai/agent/studio/dto/Thread.java","lineNumber":122,"sourceCode":"\t\t}\n\n\t\t@CanIgnoreReturnValue\n\t\t@JsonProperty(\"userId\")\n\t\tpublic Builder userId(String userId) {\n\t\t\tthis.userId = userId;\n\t\t\treturn this;\n\t\t}\n\n\t\t@CanIgnoreReturnValue\n\t\t@JsonProperty(\"values\")\n\t\tpublic Builder values(Map<String, MessageDTO> values) {\n\t\t\tthis.values = values;\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic Thread build() {\n\t\t\tif (threadId == null) {\n\t\t\t\tthrow new IllegalStateException(\"Thread id is null\");\n\t\t\t}\n\t\t\treturn new Thread(threadId, appName, userId, values);\n\t\t}\n\t}\n}\n","sourceCodeStart":104,"sourceCodeEnd":128,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-studio/src/main/java/com/alibaba/cloud/ai/agent/studio/dto/Thread.java#L104-L128","documentation":"Thrown by Thread.Builder.build() as a final invariant check: a Thread instance must always have a non-null threadId. The builder was constructed without a threadId (e.g., via the Jackson @JsonCreator no-arg constructor) and no threadId(...) setter was called before build(). It signals a programmer/marshalling error, not a runtime condition.","triggerScenarios":"Calling new Thread.Builder(null) or new Thread.Builder(id).threadId(null), then build(); deserializing JSON into the Builder via the no-arg @JsonCreator constructor when the JSON lacks \"threadId\" (or the thread_id property), then invoking build(); programmatically forgetting the mandatory threadId(...) setter.","commonSituations":"Hand-rolled Jackson deserialization binding JSON payloads missing the threadId field into the builder; refactoring code that previously passed a literal id into the constructor but now uses the no-arg builder path; copy-paste code creating threads in tests without setting the id.","solutions":["Always pass the thread id to the constructor: new Thread.Builder(\"my-thread-id\") instead of the no-arg builder.","If deserializing from JSON, ensure the payload contains the threadId property (\"threadId\" per @JsonProperty) before build() is invoked.","Guard the id before building: check for null/blank and fail early with a clear message at the call site.","If the id is generated, generate it before constructing the builder (e.g., UUID.randomUUID().toString()) rather than leaving it unset."],"exampleFix":"// before\nThread.Builder b = new Thread.Builder(); // no id set\nb.appName(app).userId(user).values(vals);\nThread t = b.build(); // IllegalStateException: Thread id is null\n\n// after\nString id = UUID.randomUUID().toString();\nThread t = new Thread.Builder(id).appName(app).userId(user).values(vals).build();","handlingStrategy":"validation","validationCode":"if (threadId == null || threadId.isBlank()) {\n    throw new IllegalArgumentException(\"threadId must be a non-blank string before building Thread\");\n}","typeGuard":"static boolean hasThreadId(Thread.Builder b, String id) { return id != null && !id.isBlank(); }","tryCatchPattern":"try {\n    Thread t = builder.build();\n} catch (IllegalStateException e) {\n    // threadId missing: log payload, supply/generated an id, and rebuild\n}","preventionTips":["Prefer the Thread.Builder(String threadId) constructor over the no-arg builder.","When deserializing JSON, validate that the threadId property is present.","Generate ids (UUID) before constructing builders, never inside/after build()."],"tags":["builder","null-check","dto","deserialization"],"backgroundTag":"null-argument","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}