Skip to content

Fix change_processor crash when path is a directory during two-way sync#1228

Open
adv-andrew wants to merge 1 commit intorojo-rbx:masterfrom
adv-andrew:Open-source-Contribution
Open

Fix change_processor crash when path is a directory during two-way sync#1228
adv-andrew wants to merge 1 commit intorojo-rbx:masterfrom
adv-andrew:Open-source-Contribution

Conversation

@adv-andrew
Copy link
Copy Markdown

@adv-andrew adv-andrew commented Feb 17, 2026

Fixes #1206

I was running into the same crash described in the issue where Rojo would panic during two-way sync. After looking into it, the problem is that fs::write and fs::remove_file in handle_tree_event can receive a directory path instead of a file path when dealing with init scripts.

What I did:

  • Added a function resolve_init_path that checks if the path is a directory and if so, looks for the init file inside it (init.lua, init.luau, etc.)
  • Used this in the write path so it writes to the actual init file instead of trying to write to a directory
  • For the remove path, if it's a directory I used remove_dir_all instead of remove_file
  • Instead of panicking, it now logs a warning if something goes wrong

I tried to match the same init file priority order that's used in snapshot_middleware/mod.rs.

Let me know if there's anything I should change!

@adv-andrew adv-andrew changed the title fix: handle directory paths in change_processor to prevent crash during two-way sync Fix change_processor crash when path is a directory during two-way sync Feb 17, 2026
The change processor was crashing because fs::write and fs::remove_file
were being called on directory paths instead of file paths. This happens
with init scripts where the instigating source points to the directory
instead of the init file.

Added resolve_init_path to find the actual init file in a directory,
and used remove_dir_all for directory removal.

Fixes rojo-rbx#1206
@adv-andrew adv-andrew force-pushed the Open-source-Contribution branch from 48689df to 4038990 Compare February 17, 2026 07:16
Copy link
Copy Markdown
Member

@Dekkonot Dekkonot left a comment

Choose a reason for hiding this comment

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

This needs a changelog entry. There's instructions for that in CHANGELOG.md.

InstigatingSource::Path(path) => {
if let Some(Variant::String(value)) = changed_value {
fs::write(path, value).unwrap();
match resolve_init_path(path) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You should be able to use snapshot_middleware::get_dir_middleware here instead. You'll have to change the visibility of that function but I'd prefer that to recreating the same behavior of finding an init path. Keeps things in one place and all that.

@Dekkonot Dekkonot added scope: cli Relevant to the Rojo CLI two-way-sync This will help further two-way-sync. labels Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: cli Relevant to the Rojo CLI two-way-sync This will help further two-way-sync.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Change processor tries to write to directory as if it were a file sometimes

2 participants