Skip to content

fix(whisper): honour positional listen address argument - #11652

Merged
localai-org-maint-bot merged 2 commits into
mudler:masterfrom
SomSamantray:fix/whisper-positional-addr
Sep 11, 2026
Merged

fix(whisper): honour positional listen address argument#11652
localai-org-maint-bot merged 2 commits into
mudler:masterfrom
SomSamantray:fix/whisper-positional-addr

Conversation

@SomSamantray

Copy link
Copy Markdown
Contributor

Description

This PR fixes #11623

The whisper backend parsed its gRPC listen address exclusively through Go's flag package (-addr), while backend/go/whisper/run.sh forwards launcher arguments verbatim (exec "$CURDIR"/whisper "$@"). A bare positional address was silently dropped by flag.Parse(), so the server always bound the default localhost:50051 instead of the port LocalAI actually allocated — LocalAI then connected to its allocated port, found nothing there, and failed with a misleading rpc error: code = Unavailable ... EOF.

What changed

  • backend/go/whisper/main.go: new resolveAddr helper that resolves the listen address in this order:
    1. an explicitly set -addr flag (detected via flag.FlagSet.Visit, so -addr localhost:50051 explicitly still wins over a positional),
    2. the first positional argument (the launcher-passed address),
    3. the previous default (localhost:50051) for no-argument launches.
      An explicitly empty -addr="" is treated as unset rather than binding an OS-chosen port on all interfaces.
  • backend/go/whisper/addr_test.go: Ginkgo v2 specs covering all resolution branches (explicit flag wins, explicit-default wins over positional, positional fallback, no-arg default, first-positional-wins, empty-flag-as-unset).

Scope note: 31 other Go backends under backend/go/ share the same flag-only parsing pattern and could hit the same failure. This PR intentionally keeps the fix scoped to the reported backend; happy to follow up with a shared helper for the rest if maintainers agree.

Testing

  • go build ./backend/go/whisper/ — clean
  • go test ./backend/go/whisper/ -count=1 — all specs pass (6 new address-resolution specs + existing suite)
  • go vet ./backend/go/whisper/ — clean (one pre-existing warning in untouched gowhisper.go)
  • gofmt -l backend/go/whisper/ — clean

Notes for Reviewers

  • The address-resolution logic is covered by unit tests at the exact seam main() uses; a full runtime smoke of the built binary requires natively building libgowhisper (cmake build of whisper.cpp) and was not run here.
  • This change was developed with AI assistance per .agents/ai-coding-assistants.md; attribution is recorded via the Assisted-by: commit trailers. All code was reviewed and tested by the human submitter.

Signed commits

  • Yes, I signed my commits.
  • Documentation updated (docs/content/) for user-facing changes, or not applicable

The whisper backend parsed its gRPC listen address exclusively through
Go's flag package, while run.sh forwards launcher arguments verbatim.
A bare positional address was silently dropped by flag.Parse(), so the
server always bound the default localhost:50051 instead of the port its
caller allocated — LocalAI then failed to reach it with a misleading
'error reading from server: EOF'.

Fall back to the first positional argument when no explicit -addr value
was given, keeping the default for no-argument launches.

Fixes mudler#11623

Assisted-by: ox-alpha:ox-alpha [go test]

Signed-off-by: Som Samantray <som.samantray@gmail.com>
…st style

Review follow-up:
- Detect an explicitly set -addr with flag.FlagSet.Visit instead of
  comparing against the default sentinel, so '-addr localhost:50051'
  plus a positional argument keeps the flag value.
- Treat an explicitly empty -addr as unset rather than binding the
  empty address (OS-chosen port on all interfaces).
- Rewrite addr_test.go as Ginkgo v2 specs per .agents/coding-style.md;
  stdlib t.Run/t.Errorf are forbidden by .golangci.yml forbidigo.

Assisted-by: ox-alpha:ox-alpha [go test]

Signed-off-by: Som Samantray <som.samantray@gmail.com>

@localai-org-maint-bot localai-org-maint-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The positional-address fallback preserves explicit -addr precedence and the existing no-argument default, and the focused specs cover the edge cases. DCO passes; normal CI has not reported yet. The targeted package test is currently blocked by generated protobuf symbols missing on the base branch, unrelated to this two-file diff. Good to merge once the remaining checks are green. @mudler

@localai-org-maint-bot

Copy link
Copy Markdown
Collaborator

Review pass. The code is clean and the specs are proper Ginkgo, but I could not find the failure mode in the tree, so this needs a maintainer call on whether it is fixing a real in-product bug.

What I checked. Every backend spawn passes the address as a flag: pkg/model/process.go:288 does append(args, "--addr", serverAddress) and is reached from both pkg/model/initializers.go:136 and core/services/worker/supervisor.go:458 with no extra args, and the e2e harness uses --addr= at tests/e2e-backends/backend_test.go:333. I also checked v4.8.2 (5ff25d9d1, the version named in #11623) and it already passed --addr there too.

The reproduction in the issue is a manual ./run.sh 127.0.0.1:59999, which is not how LocalAI invokes the backend. So the in-product failure reported in #11623 most likely has a different cause that this PR does not touch. Worth confirming with the reporter before merging, otherwise the issue gets closed while the real problem stays open.

On the change itself: flag.Visit is the correct way to distinguish an explicitly-set flag from a default, and the help-text correction from "the address to connect to" to "the address to listen on" is a good drive-by. If the positional form ever were used, note that Go's flag stops parsing at the first non-flag token, so a caller putting a positional before --addr would make the server bind that positional string.

Consistency question: backend/go/piper/main.go:12 and backend/go/silero-vad/main.go:12 are byte-for-byte the same pattern and are untouched here. If the positional convention is worth supporting, whisper should not be the only one; if it is not, this is a manual-invocation ergonomic rather than a fix. Either way it should be consistent.

DCO is clean on both commits.

@localai-org-maint-bot

Copy link
Copy Markdown
Collaborator

I don't think this is the right fix, because the premise in #11623 doesn't hold: LocalAI does not pass the listen address positionally.

pkg/model/process.go builds the backend's argv as:

process.WithArgs(append(args, []string{"--addr", serverAddress}...)...)

That is a normal flag, which flag.Parse() handles correctly. And it is not a recent change — git show v4.8.2:pkg/model/process.go has the identical line, and v4.8.2 is the exact version the issue was filed against.

The reproduction in the issue is:

./run.sh 127.0.0.1:59999

That is a hand invocation with a bare positional argument. LocalAI itself invokes run.sh --addr 127.0.0.1:63508, which whisper's main.go already parses. Binding :50051 when handed an unrecognised positional is correct behaviour, not the bug.

Two consequences:

  1. Whatever actually caused the reporter's Backend process exited unexpectedly ... exitCode=2 is still unexplained. Merging this would close a live report while the real failure is untouched.
  2. All 31 backends under backend/go/* use the identical flag.String("addr", ...) pattern with no positional handling. If positional support were genuinely needed, adding a bespoke resolveAddr to one of them would be the wrong layer — it belongs in the shared launcher or in pkg/grpc.

The resolveAddr helper and its specs are well written, so if you do want positional support as a general convenience that is a reasonable thing to propose — but it should be framed that way and applied uniformly, not as a fix for #11623.

Worth getting @kamilsa to re-check with --addr in the argv to find the actual cause.

@localai-org-maint-bot
localai-org-maint-bot merged commit d27fb32 into mudler:master Sep 11, 2026
65 checks passed
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.

whisper backend run.sh forwards LocalAI's positional listen address, but main.go only parses -addr flag — backend always binds :50051

2 participants