Repository navigation
Conversation
…le, and replaces other existing files only when told to
A composition made from footage.mp4 is named after the file, so its default output was
<project folder>/footage.mp4: the footage itself. Render opened it with File::create and
truncated it, without asking.
- A render never writes over a file the project reads: footage (every frame of a sequence),
a proxy, or the project file. Paths are compared through links and, on Windows and macOS,
without regard to case. The item fails with the reason and the other items render, with
overwrite or without it.
- Any other file that exists is replaced only with renderQueue.render {overwrite: true}; without
it the whole render is refused before anything is written and the queue is left as it was.
renderQueue.checkOutputs reports what would be replaced (existing) or refused (blocked).
- The desktop app asks Replace / Cancel before replacing (Escape cancels; automation ids
dialog.overwrite.replace and dialog.overwrite.cancel). effectcraft-cli render takes
--overwrite, scripts take renderQueue.render(true), and a watched folder keeps replacing the
outputs of a project it renders again.
- A default output name that would be one of those files is numbered when the item is added
(comp "footage" renders to footage_1.mp4, as After Effects numbers a second item of one comp).
A name the caller chose is kept, and rendering it is refused.
Tests: engine (tests_render_overwrite, output_guard), project (sequence_frame, numbered_template),
UI (ui_render_overwrite), CLI end to end, host (script render(true)).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The prompt that asks before a render replaces an existing file had no rows in the panel catalogs, so it read in English whatever the language. Nine strings now have a row in each of the seven catalogs (ja, zh-hans, zh-hant, uk, pt-br, cs, es), using each catalog's own words for file, render and frame. The sums that carry a count are written so they read correctly for any number. In Japanese and Chinese the question sentences in the body end with an ASCII question mark: the full-width one drew in a heavier fallback font in body text. The titles keep the full-width mark, which renders correctly there. I looked at the prompt in every language, for one file and for several, and none overflows the dialog. A test keeps it that way: it fails if any of the strings has no row in any language, and checks that the file name still comes before its folder. The translations were written without a native speaker; a review by one is welcome. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Comment |
The sequence line of the Replace / Cancel prompt kept the English word, while the rest of the Portuguese catalog says "quadros". Found in review. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The prompt holds the render until Replace is pressed, and the answer then went with `overwrite: true` for whatever the queue's outputs were at that moment. An agent can run `renderQueue.setOutput` over the control channel while the prompt is open, so a file the prompt never showed could be replaced by the same answer. Replace now checks the queue's outputs again. If they are the ones the prompt listed, the render runs with `overwrite: true` as before. If they changed, the render stays pending and the prompt asks again about what is there now. If nothing is left to replace, or the check fails, the render runs without permission to replace and the engine decides. Found in review. Tests: a test that points the queue at another existing file while the prompt is open (nothing is replaced, it asks again, and answering replaces that file; it fails without the change), and one for the case where the listed file is gone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The check compared an output only with footage that has the same file name, so an existing hard link to footage under another name was found as an ordinary file that exists. With overwrite, the exporter's File::create then truncated the one file both names lead to, and the footage was gone. Found in review. A render output that exists, and has the size of some footage, is now compared with it by the volume's own identity (the `same-file` crate: the device and inode on Unix, the volume and file index on Windows). Nothing is asked of a file that does not exist, so rendering to a new file costs one look, and the footage sizes are read once, when first needed. `same-file` was already in the lock file (through walkdir) and is Unlicense or MIT; it is a dependency of the engine on native targets only. Tests: a hard link to the footage is refused and left alone (it fails without the change), and a copy of the footage, which has its size and bytes but is another file, is still replaceable. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…efault names avoid the queue's other outputs
Two queue items that resolve to one output (the same comp added twice, a duplicated item) replaced
each other's file inside one job. Nothing is on disk when the job starts, so the check for existing
files said nothing.
- A default output name (renderQueue.add, render.preRender, comp.saveFrameAs {queue},
file.createProxy) that another item of the queue writes, in any output module or segment, is
numbered like a footage collision: Main.mp4, Main_1.mp4, Main_2.mp4 (as After Effects numbers a
second item of one comp). Sequences are compared by the frames they write, so two stills of one
comp at different times keep their names. Names a caller gave and names already stored in items
are never changed; the stored name keeps it stable when the item it avoided is removed.
- Outputs of one job that still name the same file (explicit names, renderQueue.duplicate,
output modules, segments) are listed by renderQueue.checkOutputs under `duplicates` and the whole
render is refused before anything is written, naming both items. Sequences clash only on frames
both write; a later item with Skip Existing Files leaves the earlier one's frames alone; items
refused for footage and items outside the job take no part.
Why refuse the whole render, regardless of `overwrite`: that flag means "replace files that exist
on disk"; here the render would replace its own output, so there is nothing for the user to
approve, and which of two items should keep the file is theirs to say. Failing only the later item
would leave a half-rendered queue found after the user left; refusing tells them at the click and
writes nothing. renderQueue.duplicate stays a verbatim copy so the clash is reported, not hidden.
The Replace / Cancel prompt stays closed when duplicates exist; the engine's message reaches the
status bar.
Tests: engine (tests_render_overwrite, output_guard unit tests), ui-egui (ui_render_overwrite).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… request for --overwrite With existing files and two queue items writing one file, the CLI's own check said 'pass --overwrite', and the flag then changed nothing. It now leaves duplicates to the engine's refusal, which names both items. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
nanox333
force-pushed
the
fix/1743-duplicate-outputs
branch
from
October 19, 2026 05:45
3cd6ec1 to
69006ff
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #1743, the third of three parts. The first is #1758, which closes the issue.
Draft: stacked on #1758. This branch contains #1758's five commits, so until #1758 merges the diff below also shows them. This PR's own changes are the last two commits (10 files, +834/-27). I will rebase it and mark it ready for review once #1758 has merged. It does not depend on the second part.
What was wrong
Two queue items that resolve to one output (a comp added twice, a duplicated item) replace each other's file inside one job. Nothing is on disk when the job starts, so the existing-file check said nothing.
What changes
Main.mp4,Main_1.mp4(renderQueue.add,render.preRender,comp.saveFrameAs {queue},file.createProxy). Names a caller gave and names already stored in items are never changed. Sequences are compared by the frames they write, so two stills of one comp at different times keep their names.renderQueue.duplicate, output modules, segments) are listed byrenderQueue.checkOutputsunderduplicates, and the whole render is refused before anything is written, naming both items.overwritedoes not apply: it is for files that exist, and here the render would replace its own output. Sequences clash only on frames both write; a later item with Skip Existing Files leaves the earlier item's frames alone; items refused for footage take no part.effectcraft-cli renderno longer asks for--overwritefirst.Behaviour changes
A job that used to render two items over one file now refuses before writing anything. Default names change only for new items that would collide.
Testing
tests_render_overwriteandoutput_guardunit tests,ui_render_overwrite(two_items_writing_one_file_are_refused_without_asking_to_replace) and a CLI test. They were written to fail without the change; I have not re-run them without it since the rebase onto Fix #1743: protect render outputs from replacing project sources #1758.cargo fmt --check;cargo testfor effectcraft-engine (lib, 700 passed), -project, -host (lib), -automation (45 + 8), -cli (cli.rs, 23 passed) and -ui-egui (lib i18n and overwrite,ui_render_overwrite8 tests,ui_render_queue,ui_agent_audit);cargo clippy -D warningson the engine's library and on project, host, ui-egui, automation, script and cli (all targets);cargo xtask layers;cargo check --target wasm32-unknown-unknownfor project, engine and ui-egui.cargo xtask cigate not run; quick checks only.