Skip to content

Fix ProviderError and git worktree path conflict failures#552

Open
studiozeroseven wants to merge 2 commits intospacedriveapp:mainfrom
studiozeroseven:fix-spacebot-issues
Open

Fix ProviderError and git worktree path conflict failures#552
studiozeroseven wants to merge 2 commits intospacedriveapp:mainfrom
studiozeroseven:fix-spacebot-issues

Conversation

@studiozeroseven
Copy link
Copy Markdown

@studiozeroseven studiozeroseven commented Apr 9, 2026

Description

This PR fixes multiple stability issues within the Spacebot orchestration layer:

  1. ProviderError (Streaming Data): The streaming parser previously crashed with TrailingCharacters if LLMs hallucinated extra noise outside of the JSON tool call block. The fix leverages a JSON stream chunk .next() extractor which naturally isolates the first valid JSON blob and purposefully ignores arbitrary trailing text.
  2. Git Worktree Path Res & Add Failures: The project_manage tool previously caused multi-repo environments to conflict when branches shared names with tracked repositories. We now safely place multirepo worktrees underneath a merged - namespace. As an extra layer of robust environment tear-downs, --force is added to git worktree removal.
  3. UTF-8 Slicing Panics (Issues Remaining UTF-8 char boundary panics in channel.rs and signal.rs (incomplete fix from #273) #518): Replaced brute-force substring slices like &conclusion[..200] with &conclusion[..conclusion.floor_char_boundary(200)] in channel.rs and signal.rs. This prevents panics caused by multi-byte emojis or non-ASCII characters on boundaries.
  4. Slack Enterprise Routing Limitations (Issue Cron delivery fails for Enterprise Slack workspaces — is_valid_instance_name misidentifies workspace IDs #520): Adapted the Slack workspace ID rejection logic in is_valid_instance_name (target.rs) to include E prefixes, protecting large Enterprise setups from misrouting errors by preventing them from being misclassified as a user-configured named instance.
  5. LiteLLM Model Name Bug (Issue Add LiteLLM provider support #507): Applied a clean fallback replacement stripping litellm/ from forwarded completion requests in remap_model_name_for_api (model.rs) uniformly.

Tested locally, resulting in clean passing tests on CI. Let me know if there are any questions.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

Walkthrough

Formatting and UTF‑8-safe truncation fixes across messaging and agent code, JSON stream deserialization robustness and model-name remapping updates, git worktree removal force flag, and multi-repo worktree naming to include repository name.

Changes

Cohort / File(s) Summary
Agent & Messaging text/truncation
src/agent/channel.rs, src/messaging/signal.rs
Converted several built-in/help text literals to multi-line .to_string() usage; replaced byte-slice truncation with Unicode-safe truncation using floor_char_boundary(200) for logged/summary text.
Config log formatting
src/config/load.rs
Expanded a single-line tracing::warn! into a multi-line invocation; message text and behavior unchanged.
LLM streaming & model remap
src/llm/model.rs
Parse streamed tool arguments via serde_json::Deserializer::from_str(...).into_iter() and explicitly error on empty JSON streams; strip litellm/ prefix before provider-specific remapping.
Git & project worktree management
src/projects/git.rs, src/tools/project_manage.rs
Added --force to git worktree remove invocation; multi-repo worktrees now include repo.name prefix in created directory and DB entry to avoid name conflicts.
Instance-name validation
src/messaging/target.rs
Refined Slack-workspace-ID rejection heuristic: now rejects names length >=6 that start with T, C, or E and whose suffix is all ASCII uppercase letters or digits (adjusted boundary/character checks).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • jamiepine
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: ProviderError handling for streaming data and git worktree path conflict fixes are the primary focuses addressed across the modified files.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing five specific stability fixes across multiple files that align with the raw summary of changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/projects/git.rs (1)

251-260: ⚠️ Potential issue | 🟡 Minor

Update the function doc to reflect forced removal.

Line 253 says git worktree remove <worktree_path>, but Line 260 now runs with --force. Please document that behavior explicitly to avoid accidental misuse.

📝 Suggested doc update
-/// Runs `git worktree remove <worktree_path>`.
+/// Runs `git worktree remove --force <worktree_path>`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/projects/git.rs` around lines 251 - 260, Update the docstring for the
function remove_worktree to explicitly state that it performs a forced removal
(it runs `git worktree remove --force <worktree_path>`), so callers know this
can discard local changes; adjust the first line and description to mention the
use of the --force flag and its implication rather than the current non-forced
command text.
src/tools/project_manage.rs (1)

643-658: ⚠️ Potential issue | 🟠 Major

Multi-repo worktree path can still collide at project root.

Line 657 places worktrees at root/<repo>-<worktree>. That can still conflict with existing top-level repo directories, and it also contradicts the .worktrees/... behavior described on Line 644.

🛠️ Suggested fix (dedicated namespace)
-        // For multi-repo projects, place them inside the project root,
-        // prefixed with `.worktrees/repo_name-worktree_name` to avoid conflicts.
+        // For multi-repo projects, place them under a dedicated `.worktrees`
+        // namespace using `repo_name-worktree_name` to avoid root-level collisions.
         let (worktree_abs_path, worktree_db_path) = if is_single_repo {
             let parent = root.parent().ok_or_else(|| {
                 ProjectManageError("single-repo project root has no parent directory".into())
             })?;
             (
                 parent.join(&worktree_dir_name),
                 format!("../{worktree_dir_name}"),
             )
         } else {
-            // Include repo name in the worktree directory name to avoid conflicts
-            // with other repos or their worktrees in a multi-repo project.
+            // Include repo name and store under `.worktrees/` for strong namespacing.
             let dir_name = format!("{}-{}", repo.name, worktree_dir_name);
-            (root.join(&dir_name), dir_name)
+            let db_path = format!(".worktrees/{dir_name}");
+            (root.join(&db_path), db_path)
         };
// Before git::create_worktree(...) call:
if !is_single_repo {
    tokio::fs::create_dir_all(root.join(".worktrees"))
        .await
        .map_err(|error| {
            ProjectManageError(format!("failed to create .worktrees directory: {error}"))
        })?;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/tools/project_manage.rs` around lines 643 - 658, The current multi-repo
branch still places worktrees directly under root as root/<repo>-<worktree>,
which can collide with top-level repo dirs and contradicts the documented
`.worktrees/...` namespace; change the multi-repo branch so it creates and uses
a dedicated `.worktrees` directory under root (e.g.,
root.join(".worktrees").join(format!("{}-{}", repo.name, worktree_dir_name)))
and ensure you create the `.worktrees` directory before use (propagate errors as
ProjectManageError), updating the variables used later (worktree_abs_path and
worktree_db_path) so they reference the `.worktrees` namespaced path instead of
root/<repo>-<worktree>; keep single-repo behavior unchanged and ensure the
created path is passed to git::create_worktree call.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/projects/git.rs`:
- Around line 251-260: Update the docstring for the function remove_worktree to
explicitly state that it performs a forced removal (it runs `git worktree remove
--force <worktree_path>`), so callers know this can discard local changes;
adjust the first line and description to mention the use of the --force flag and
its implication rather than the current non-forced command text.

In `@src/tools/project_manage.rs`:
- Around line 643-658: The current multi-repo branch still places worktrees
directly under root as root/<repo>-<worktree>, which can collide with top-level
repo dirs and contradicts the documented `.worktrees/...` namespace; change the
multi-repo branch so it creates and uses a dedicated `.worktrees` directory
under root (e.g., root.join(".worktrees").join(format!("{}-{}", repo.name,
worktree_dir_name))) and ensure you create the `.worktrees` directory before use
(propagate errors as ProjectManageError), updating the variables used later
(worktree_abs_path and worktree_db_path) so they reference the `.worktrees`
namespaced path instead of root/<repo>-<worktree>; keep single-repo behavior
unchanged and ensure the created path is passed to git::create_worktree call.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0d8460a3-4ef2-434e-a60c-775b57c84085

📥 Commits

Reviewing files that changed from the base of the PR and between ac01c5b and c670f40.

📒 Files selected for processing (5)
  • src/agent/channel.rs
  • src/config/load.rs
  • src/llm/model.rs
  • src/projects/git.rs
  • src/tools/project_manage.rs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/messaging/target.rs`:
- Around line 669-672: The validation now rejects Slack-style IDs starting with
'T', 'C', or 'E' in the code path that checks name length and leading character
(see the check in src/messaging/target.rs that uses
name.starts_with('T'|'C'|'E')), so update the API validation message in
src/api/messaging.rs to mention T/C/E (not just T/C) and add a new assertion in
the is_valid_instance_name_invalid_slack_workspace test in
src/messaging/target.rs to cover an 'E...' ID case (i.e., add an invalid
instance name beginning with 'E' that matches the same length/char pattern) so
tests and user-facing guidance stay consistent with the implementation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a5f259fa-17d2-41a5-bdee-c5258c781d37

📥 Commits

Reviewing files that changed from the base of the PR and between c670f40 and 53a7b52.

📒 Files selected for processing (4)
  • src/agent/channel.rs
  • src/llm/model.rs
  • src/messaging/signal.rs
  • src/messaging/target.rs
✅ Files skipped from review due to trivial changes (1)
  • src/messaging/signal.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/llm/model.rs

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.

1 participant