Skip to content

Accept "localhost:11434" and trailing slashes as the Ollama endpoint [patch] - #178

Merged
matt-edmondson merged 3 commits into
mainfrom
fix/157-endpoint-normalization
Sep 29, 2026
Merged

matt-edmondson merged 3 commits into
mainfrom
fix/157-endpoint-normalization

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #157

What was wrong

The endpoint was used exactly as typed, which broke in two ways:

  • No scheme: localhost:11434, the address Ollama prints, parsed as a URI whose scheme is localhost. IsAvailableAsync didn't catch the resulting NotSupportedException, so Scan crashed. Values like http:// or not a url threw an uncaught UriFormatException in the same way.
  • Trailing slash: the URL was built as $"{endpoint}/api/generate", so a trailing slash sent every describe request to //api/generate.

Change

  • OllamaClient.NormalizeEndpoint:
    • Trims the value, adds http:// when the scheme is missing, and drops trailing slashes.
    • Returns null unless the result is an absolute http/https URI with a host and no query or fragment.
  • OllamaClient.GetBaseUri / GetGenerateUri: the base always ends in exactly one /, and request URLs are built with new Uri(base, "api/generate"). A path prefix such as https://host/ollama/ is kept.
  • IsAvailableAsync: now also catches ArgumentException (which covers UriFormatException), NotSupportedException and InvalidOperationException, and returns false.
  • Configure: saves the normalized value. An invalid entry prints a message and keeps the current endpoint.
  • BaseVerb.Endpoint (-e/--endpoint or the saved setting): normalized when valid. Settings saved before this change are fixed up as they are read.
  • Scan: prints Error: Invalid Ollama endpoint "…" and returns before the availability check.

Tests

  • New OllamaClientTests:
    • localhost:11434, http://localhost:11434, http://localhost:11434/ and a value with surrounding spaces and a double slash all map to http://localhost:11434/api/generate.
    • A path prefix is kept.
    • Normalization cases, and rejection of empty, http://, not a url, ftp:// and query-string values.
    • IsAvailableAsync returns false for invalid endpoints.
  • ScanTests.ScanReportsAnInvalidEndpointInsteadOfCrashing runs Scan with not a url and checks for the error message.

With the source changes reverted, ScanReportsAnInvalidEndpointInsteadOfCrashing and both IsAvailableReturnsFalseForAnInvalidEndpoint rows fail with UriFormatException. The URL-building tests don't compile without the new helpers. With the change, the full suite passes: 76 tests, 1 skipped as before because the root user can read every folder.

dotnet format --verify-no-changes reports one JSON002 on the fake Ollama response string in ScanTests.StartFakeOllama. That line is unchanged on main.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Kj95GdQsZpSCcND7LqacT1


Generated by Claude Code

…[patch]

The endpoint was used exactly as typed. "localhost:11434", the address
Ollama prints, parsed as a URI with the scheme "localhost" and crashed
Scan with an unhandled NotSupportedException, and a trailing slash sent
every describe request to "//api/generate".

OllamaClient.NormalizeEndpoint now adds a missing http:// and drops
trailing slashes, and rejects anything that isn't an http or https
address. Configure saves the normalized value or keeps the old one,
-e/--endpoint is normalized too, Scan prints an "invalid endpoint" error
instead of crashing, and request URLs are built with new Uri(base,
"api/generate") rather than string concatenation.

Fixes #157

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kj95GdQsZpSCcND7LqacT1
SonarCloud failed the quality gate on coverage (69.2%) and on S5332 for
the "http://" literal. Build the default scheme from Uri.UriSchemeHttp
and Uri.SchemeDelimiter, move Configure's endpoint handling into the
testable Configure.ChooseEndpoint, and remove the NotSupportedException
and InvalidOperationException catches in IsAvailableAsync: GetBaseUri
now rejects every endpoint that could raise them, as ArgumentException.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kj95GdQsZpSCcND7LqacT1
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 9cd06b7 into main Sep 29, 2026
12 checks passed
@matt-edmondson
matt-edmondson deleted the fix/157-endpoint-normalization branch September 29, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Endpoint entered as "localhost:11434" crashes Scan with NotSupportedException, and a trailing slash produces requests to "//api/generate"

2 participants