Skip to content

Trim the deployment directory pasted into the desktop setup screen - #454

Merged
davidmckayv merged 2 commits into
CopilotKit:mainfrom
kevin9327:fix/trim-deployment-directory
Sep 9, 2026
Merged

Trim the deployment directory pasted into the desktop setup screen#454
davidmckayv merged 2 commits into
CopilotKit:mainfrom
kevin9327:fix/trim-deployment-directory

Conversation

@kevin9327

Copy link
Copy Markdown
Contributor

#417 trimmed four of the values entered on the desktop setup screen. There is a fifth on the same
screen — Where OpenBot lives — and it is still sent untrimmed, gated by the same trim() that
prompted that fix.

The gap

desktop/src/App.tsx enables Start on the trimmed value and sends the raw one:

disabled={busy || apiKey.trim() === "" || modelKey.trim() === "" || root.trim() === ""}
await invoke("start_stack", { root, apiUrl, gatewayWsUrl: wsUrl, apiKey, openaiApiKey: modelKey });

Three commands take that string and make a path of it verbatim:

// start_stack
let root = PathBuf::from(root);
// stop_stack
stop_everything(&app, &PathBuf::from(&root))
// already_running
let root = PathBuf::from(&root);

This one is not a credential, it is a place on disk, so the two ways it goes wrong are different
from the credential case:

  • A trailing space makes a second directory beside the one everything else means. The tray's
    Stop calls default_root() and the next launch is offered default_root() again, and neither has
    the space in it — so the deployment that was laid down is one nothing on screen reaches: Stop runs
    compose down in the wrong tree, and starting again re-fetches the whole release into the other
    directory.
  • A leading space is worse. A path that begins with a space does not begin with a separator, so
    " /home/me/OpenBot" is not absolute — Path::components reads it as " ", "Users", … and the
    deployment is laid out relative to wherever the window is running from.

A path picks these up the same way a key does: copied out of a document, or dragged in with the
newline at the end of the line.

The change

One trim, at the point the typed string becomes a path, named so all three commands share it. Both
ends only — a space inside a path is part of a directory's name.

Failing first

main has no such function, so the fail-before run implements root_from as main's own rule,
which is PathBuf::from(typed) at each of the three call sites, and nothing else:

pub fn root_from(typed: &str) -> PathBuf {
    PathBuf::from(typed)
}
$ RUSTUP_TOOLCHAIN=1.98.0-x86_64-pc-windows-msvc cargo test --manifest-path desktop/src-tauri/Cargo.toml --lib stack::
running 15 tests
test stack::tests::a_space_inside_the_path_is_part_of_the_path ... ok
...
test stack::tests::a_deployment_directory_pasted_with_a_stray_space_is_the_one_it_names ... FAILED

---- stack::tests::a_deployment_directory_pasted_with_a_stray_space_is_the_one_it_names stdout ----

thread 'stack::tests::a_deployment_directory_pasted_with_a_stray_space_is_the_one_it_names' (34928) panicked at src\stack.rs:655:9:
assertion `left == right` failed
  left: "  /home/me/OpenBot  "
 right: "/home/me/OpenBot"

failures:
    stack::tests::a_deployment_directory_pasted_with_a_stray_space_is_the_one_it_names

test result: FAILED. 14 passed; 1 failed; 0 ignored; 0 measured; 72 filtered out; finished in 4.04s

With typed.trim():

$ RUSTUP_TOOLCHAIN=1.98.0-x86_64-pc-windows-msvc cargo test --manifest-path desktop/src-tauri/Cargo.toml
test result: ok. 87 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.08s

85 of those 87 are the suite as it stands on main, all still passing.

Against over-correcting

a_space_inside_the_path_is_part_of_the_path pins what must still come through untouched, and it
passed in the failing run above as well as after the change — the trim must not reach inside the
path:

  • /home/me/My Files/OpenBot — a home directory with a space in it.
  • C:\Users\me\Open Bot — the same on Windows.
  • /home/me/OpenBot — an ordinary path, handed back exactly as it was.

The trade this does make is that a directory whose name genuinely ends in a space can no longer be
named from this box. That is the same trade #417 made for the credentials, for the same reason: the
screen's own enable check already treats the trimmed value as the value, so a person who typed one
was going to be told the button was available and then given something else.

Verified with

RUSTUP_TOOLCHAIN=1.98.0-x86_64-pc-windows-msvc cargo test   --manifest-path desktop/src-tauri/Cargo.toml
RUSTUP_TOOLCHAIN=1.98.0-x86_64-pc-windows-msvc cargo clippy --manifest-path desktop/src-tauri/Cargo.toml --all-targets
RUSTUP_TOOLCHAIN=1.98.0-x86_64-pc-windows-msvc cargo fmt    --manifest-path desktop/src-tauri/Cargo.toml -- --check

clippy finished with no warnings on the crate; fmt --check is clean.

Note on the changelog

A deployment behaves differently afterwards — the directory a person names is the directory that is
used — so there is a ## Unreleased entry. It shares that anchor with other open pull requests and
may need a one-line rebase.

The screen enables Start on `root.trim() !== ""` and then sent the untrimmed
string -- the same trap the four settings beside it were taken out of. A
trailing space makes a second directory beside the one `default_root` names, so
the tray's Stop and the next launch look somewhere else; a leading space stops
the path being absolute, so the deployment lands wherever the window is running
from. Trimmed at both ends now, with spaces inside the path left alone.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@davidmckayv davidmckayv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Deep-reviewed against the real Rust (no exfil/backdoor/injection; correctness verified). Both CI and Desktop (rust build) green on this head. CHANGELOG rebase on validated substance.

@davidmckayv
davidmckayv merged commit 1c7bd92 into CopilotKit:main Sep 9, 2026
18 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.

2 participants