spring-projects/spring-ai · error · java.lang.IllegalStateException
signature must be set when text is set
Error message
signature must be set when text is set
What it means
BedrockReasoningContent.Builder.build enforces the Bedrock invariant that reasoning text must always be accompanied by a signature (used to verify the reasoning when replayed). Calling build() with text set but signature null throws this IllegalStateException.
Solutions
- Always pass the signature from the original ReasoningTextBlock alongside the text.
- Persist both reasoningText.text() and reasoningText.signature() from prior turns and replay both.
- If you have no signature, omit the text too — build a redactedContent-only reasoning block or drop the block.
- Capture the signature at first receipt (BedrockReasoningContent.getSignature()) before serialization.
Example fix
// before
BedrockReasoningContent.builder()
.text(previous.getReasoningText())
.build();
// after
BedrockReasoningContent.builder()
.text(previous.getReasoningText())
.signature(previous.getReasoningSignature())
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (text != null && signature == null) {
throw new IllegalArgumentException("Cannot replay reasoning without signature");
} Type guard
boolean isReplayable(BedrockReasoningContent rc) {
return rc.getText() == null || rc.getSignature() != null;
} Try / catch
try {
content = builder.build();
} catch (IllegalStateException e) {
if (e.getMessage().contains("signature must be set")) {
// drop text or supply signature before rebuilding
} else throw e;
} Prevention
- Persist signature together with reasoning text from every reasoning turn
- Never reconstruct reasoning content from text-only logs
- Use BedrockReasoningContent getters to copy both fields when replaying
- Add an assert in serialization helpers that signature accompanies text
When it happens
Trigger: Programmatically building a BedrockReasoningContent (typically to replay reasoning in multi-turn tool-use conversations) via Builder.text(...) without calling .signature(...).
Common situations: Replaying assistant reasoning during multi-turn conversations: developers copy the text but drop the signature field; manually reconstructing reasoning content from logs that omitted the signature.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Unexpected reasoningContent block: neither reasoningText…
- argumentConsumer is required
- Bean must not be null
- Bean must not be null
- Bean must not be null
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/6dbc5bfd577f80fa.
Report an issue: GitHub.
Appendix: source
Thrown at models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockReasoningContent.java:169
public Builder text(@Nullable String text) {
this.text = text;
return this;
}
public Builder signature(@Nullable String signature) {
this.signature = signature;
return this;
}
public Builder redactedContent(byte @Nullable [] redactedContent) {
this.redactedContent = redactedContent != null ? redactedContent.clone() : null;
return this;
}
public BedrockReasoningContent build() {
if (this.text != null && this.signature == null) {
throw new IllegalStateException("signature must be set when text is set");
}
return new BedrockReasoningContent(this.text, this.signature, this.redactedContent);
}
}
}
View on GitHub (pinned to 98a7beda4f)