Skip to content

fix: two long-standing papercuts in the migration CLI and agent import - #87

Open
antiv wants to merge 1 commit into
mainfrom
claude/migrate-cli-and-import-errors
Open

fix: two long-standing papercuts in the migration CLI and agent import#87
antiv wants to merge 1 commit into
mainfrom
claude/migrate-cli-and-import-errors

Conversation

@antiv

@antiv antiv commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Two one-line fixes, both surfaced while working on #79/#82/#83. Neither is a regression — both have been there since the code was written.

1. python shared/migrate.py has never worked

shared/migrate.py imports its dependency relatively (from .utils.migration_system import ...) while being invoked as a script, so every command dies on ImportError: attempted relative import with no known parent package before doing anything.

That form is documented in three places — CLAUDE.md:46-49, README.md:256-259, CONTRIBUTING.md:101 — and the sys.path.append(parent) already at the top of the file (line 18) shows script invocation was the intent all along. So the import is what is wrong, not the docs.

An absolute import makes both invocation styles work:

python shared/migrate.py status   # documented form — was broken
python -m shared.migrate status   # the workaround — still works

2. agents/import blamed the wrong thing for its failures

The handler raised its own HTTPException inside a try whose except Exception then swallowed and rewrapped it. Every import failure reached the dashboard as:

Invalid JSON data: 400: Invalid import format: missing 'agents' array

— naming the request body as the cause of a failure that had nothing to do with parsing it. The status code stayed 400 by coincidence; the message did not.

Seventeen other handlers in the same file already re-raise HTTPException first. This one was the outlier. The except Exception branch keeps its real job: a genuinely unparseable body still reports "Invalid JSON data".

Tests

  • shared/test/test_migrate_cli.py (3 tests) — drives the CLI as a subprocess in both invocation styles. Invoked with no arguments it prints usage and exits before constructing MigrationSystem, so the tests never touch a database.
  • shared/test/test_import_error_message.py (3 tests) — a rejected import reports its own reason; an unparseable body still says so; a successful import is unaffected.

Verified the tests fail against the unpatched code (3 of 6 fail). Full suite: 731 tests, all passing.

Merges cleanly with #85, which touches the same handler — checked; the combined result keeps both the audit call and the re-raise.

🤖 Generated with Claude Code

Both surfaced while working on #79/#82/#83. Neither is a regression; both
have been there since the code was written.

1. `python shared/migrate.py run` — the form documented in CLAUDE.md,
   README.md and CONTRIBUTING.md — has never worked. The module imports its
   dependency relatively while being invoked as a script, so every command
   died on ImportError before doing anything. The `sys.path.append(parent)`
   already at the top of the file shows script invocation was the intent, so
   the import is what is wrong, not the docs. An absolute import makes both
   `python shared/migrate.py` and `python -m shared.migrate` work.

2. `POST /dashboard/api/agents/import` raised its own HTTPException inside a
   try whose `except Exception` then swallowed and rewrapped it, so every
   import failure reached the dashboard as
   "Invalid JSON data: 400: <real reason>" — blaming the request body for a
   failure that had nothing to do with parsing it. Seventeen other handlers
   in the same file already re-raise HTTPException first; this one was the
   outlier. The except branch still handles a genuinely unparseable body.

Co-Authored-By: Claude Opus 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