Skip to content

fix(download): rerunning -o for the same task passes; its recovery is that rerun [ENG-4886] - #30

Merged
yujiaxu-ops merged 1 commit into
mainfrom
yujiaxu/eng-rerun-o
Oct 27, 2026
Merged

yujiaxu-ops merged 1 commit into
mainfrom
yujiaxu/eng-rerun-o

Conversation

@yujiaxu-ops

Copy link
Copy Markdown
Collaborator

Two problems agents reported:

  • Rerunning get <id> -o <dir> exited 11 because the task's own files were already there.
  • When a download failed part-way, the recovery command was meshy download … --output-dir <dir>. It had a placeholder, and even with a real path filled in it hit the same existing files.

What changes

  • The sidecar decides ownership.
    • If meta.json (or <stem>_meta.json) belongs to the same resource and task, a rerun replaces the files it lists and fetches whatever is missing.
    • The new sidecar keeps listing earlier files that are still on disk. So a default rerun after an --all-assets run still records the textures.
    • Anything else already at a target path is refused before any download (local_io, exit 11, choose_path). That covers a stray file, a sidecar from another task, and an unreadable sidecar.
  • A download that fails part-way still writes the sidecar for the files that landed, and downloads.metadata_path points to it.
  • The recovery is the same -o again: meshy <resource> get <id> -o <abs path>, with --all-assets and --workspace added when they were given. It is shell-quoted, so it runs as-is from any directory. Task verbs and make now take this command from the downloader. The <dir> fallback is gone.
  • create and make with -o: if the target already has a sidecar, the command is refused before the POST. A new task would never own those files, so this avoids paying for a task that then cannot be saved.

Why ownership is not decided by comparing file contents

For an OBJ set the CLI rewrites the MTL after download. The MTL on disk therefore never matches the served bytes, so a content comparison would refuse every OBJ rerun.

Tests

  • pnpm typecheck is clean. pnpm test: 574/574 pass.
  • N06/N08: after a 503 or Ctrl-C, the sidecar lists the files that landed and the recovery is the same get -o. This includes make.
  • tests/download.test.ts covers ownership: the same task, the --all-assets union, another task, a stray file, and single-file mode.
  • tests/output-rerun.test.ts, end to end:
    • a 503 on the thumbnail;
    • the recovery run as-is from a different directory, with a path containing a space and a quote, which completes the set;
    • a second rerun of the complete set;
    • a create preflight with zero requests sent.
  • Live: two real tasks, each run with get -o twice, every run exiting 0.
    • an image-to-3d task;
    • an OBJ remesh task, where the MTL was relinked correctly both times.

Docs

usage.md, scripting.md, the exit 7/130 bullet in SKILL.md, D-086, and D-045 marked partly superseded.

Not in scope: animation catalog data

The catalog rows are in meshyd's AnimationResource table, which operators edit through admin endpoints. The CLI passes them through unchanged.

  • Basic_Jump named "Jump Attack" was decided in SUP-8456 on 2026-10-20.
  • id 89 "Combat Idel" is a typo.
  • id 258 "Crouchlookaroundbow" is missing its spaces.

Linear: ENG-4886

🤖 Generated with Claude Code

… that rerun [ENG-4886]

Rerunning `get <id> -o <dir>` exited 11 on the task's own files, and a
transfer that failed part-way (exit 7, 130) handed out
`meshy download ... --output-dir <dir>`, a placeholder that, filled in,
hit the same files.

The sidecar now decides ownership. When meta.json (or <stem>_meta.json)
belongs to the same resource and task, the files it lists are replaced
by the rerun and the rest are fetched; the new sidecar keeps listing the
earlier files still on disk. Anything else already at a target is
refused before any transfer (local_io, choose_path).

A transfer that fails part-way writes the sidecar for what landed, and
its recovery is the same -o: `meshy <resource> get <id> -o <abs path>`
plus --all-assets / --workspace when given, shell-quoted. task verbs and
make take it from the downloader instead of building their own.

create/make refuse an -o whose sidecar exists before the POST: a new
task never owns another run's files.

Tests: N06/N08 assert the sidecar and the recovery; a unit test covers
ownership (same task, --all-assets union, another task, stray file, single
file); tests/output-rerun.test.ts runs the recovery verbatim (path with a
space and a quote) to completion, reruns a complete set and checks the
create preflight. Live: image-to-3d and an OBJ remesh task, `get -o` twice,
both exit 0 (MTL relinked both times).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@yujiaxu-ops
yujiaxu-ops merged commit 5291b45 into main Oct 27, 2026
5 checks passed
@yujiaxu-ops
yujiaxu-ops deleted the yujiaxu/eng-rerun-o branch October 27, 2026 16:24
Arlieeee added a commit that referenced this pull request Oct 29, 2026
This is a minor bump because #29 contains breaking changes.

- #29: `meshy project` (`init | record | show | list | rebuild-index`)
and `--project` / `--stage` are removed; `-o` with `meta.json` and
`--save-json` keep what a task produced. `--workspace` stays as a
real-path check. OBJ material maps are relinked by served name only.
- #30: rerunning `-o` for the same task replaces that task's own files;
a download that fails part-way writes its sidecar, and its recovery is
the same `-o` again.
- #21: `MESHY_CLI_CLIENT` tags the User-Agent with the product that runs
the CLI.
- #31: `meshy auth login --region cn` / `MESHY_REGION=cn` for the China
site, remembered on the profile; `api.meshy.cn` shares
`credentials.json`. Inside DeepSeek Harness the User-Agent is tagged
`dsh`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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