spring-projects / spring-projects/spring-ai
`DefaultAdvisorObservationConvention` produces a span name with stray spaces
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.5k
- Forks
- 2.9k
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 6
Description
Bug description
The span produced for ToolCallingAdvisor is named tool _calling : there is a
space before _calling and a trailing space at the end. Tool calling is on by
default, so this appears in every trace where the model calls a tool.
Environment
Spring AI 2.0.0, Spring Boot 4.1.0, Java 21. Anthropic chat model with tool
callbacks supplied by an MCP client. Traces exported over OTLP to the
OpenTelemetry Collector. The same code is present on main.
Steps to reproduce
- Build a
ChatClientwith tool callbacks and tracing to an OTLP endpoint. - Send a prompt that makes the model call a tool.
- Read the span names.
From the Collector's debug exporter, piped through cat -A so that $ marks
end of line:
Name : tool _calling $
Name : spring_ai chat_client$
Name : call$
Expected behavior
A span name with no embedded or trailing whitespace, for example tool_calling.
Minimal Complete Reproducible example
https://github.com/kycasdzxc/spring-ai-otel-example
docker compose up -d, run the app, then ask a question that triggers a tool
call. The malformed name appears in the collector output and in Tempo.
The minimal condition is narrower than that project: any advisor whose
getName() returns a string containing spaces reproduces it. ToolCallingAdvisor
is built in, so no custom advisor is needed.
Root cause
DefaultAdvisorObservationConvention#getContextualName:
return ParsingUtils.reConcatenateCamelCase(context.getAdvisorName(), "_")
.replace("_around_advisor", "")
.replace("_advisor", "");
reConcatenateCamelCase splits on camelCase boundaries, so it expects an
identifier such as ToolCallingAdvisor. ToolCallingAdvisor#getName() returns
the display form "Tool Calling Advisor", and splitting that leaves the original
spaces attached to each token:
"Tool Calling Advisor"
-> ["Tool ", "Calling ", "Advisor"]
-> "tool _calling _advisor"
-> replace("_advisor", "") -> "tool _calling "
Advisors whose name contains no spaces are unaffected: call stays call.
Either normalising whitespace in getContextualName or having advisors supply an
identifier-shaped name would fix it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at DefaultAdvisorObservationConvention#getContextualName and inspect its use of ParsingUtils.reConcatenateCamelCase, with ToolCallingAdvisor as the reproduction path. Verify the resulting span name through the provided example or collector output; done means names such as tool_calling contain no embedded or trailing whitespace while unaffected names such as call remain valid.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- observability
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100