fix(vscode,intellij): handle missing status and fix StringIndexOutOfBoundsException in completion renderer#4482
Conversation
When the Tabby server is connected but no completion model is running, the status bar shows a persistent spinning spinner because the `codeCompletionNotAvailable` status was not handled in StatusBarItem.ts. Add a case for `codeCompletionNotAvailable` that displays the warning icon with appropriate tooltip, matching the behavior of similar warning states like `rateLimitExceeded`. Also guard `currentLineSuffix[0]` access in InlineCompletionRenderer.kt with an `isNotEmpty()` check to fix a `StringIndexOutOfBoundsException` that occurs when the cursor is at the end of a line but the completion item reports a non-zero `suffixReplaceLength` (fixes TabbyML#4404). Fixes TabbyML#4418 Fixes TabbyML#4404
|
Both bugs are the kind of defensive coding gap that's hard to write tests for upfront — a constant spinner when no completion model is configured is a bad first-run experience, and a |
|
Yes — |
Summary
This PR fixes two bugs in the client extensions:
1. VSCode: Constant spinner when no completion model is running (fixes #4418)
Problem: When the Tabby server is connected but no completion model is configured, the status bar shows a persistent spinning animation. This happens because
StatusBarItem.tsdoes not handle thecodeCompletionNotAvailablestatus emitted bytabby-agent, so the icon stays as the loading spinner from the previousStartingstate.Solution: Add a
codeCompletionNotAvailablecase to the switch statement inStatusBarItem.tsthat displays the warning icon with the appropriate tooltip — consistent with other warning states likerateLimitExceeded.2. IntelliJ:
StringIndexOutOfBoundsExceptioninInlineCompletionRenderer(fixes #4404)Problem:
InlineCompletionRenderer.ktthrowsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0at line 95 (currentLineSuffix[0]) whensuffixReplaceLength == 1butcurrentLineSuffixis empty. This can happen when the completion item'sreplaceRange.endextends past the end of the actual document line (e.g., cursor at end of line or document state mismatch).Solution: Guard the
suffixReplaceLength == 1branch withcurrentLineSuffix.isNotEmpty(). When the suffix is empty, the code falls through to the existingelseblock which handles the case gracefully without accessing out-of-bounds indices.Test plan
StringIndexOutOfBoundsExceptionwhen inline completion is triggered at the end of a line