dgtlmoon/changedetection.io · critical · Exception

Migration failed: {len(missing)} watch files missing: {missi

Error message

Migration failed: {len(missing)} watch files missing: {missing[:5]}... url-watches.json remains intact, safe to retry.

What it means

A generic Exception raised in Phase 2 of migrate_legacy_db_format: after saving each watch, the migration verifies that <datastore>/<uuid>/watch.json exists for every uuid in url-watches.json. If any are missing it aborts, listing up to five offending uuids, with url-watches.json again left intact for a safe retry.

Source

Thrown at changedetectionio/store/updates.py:617

                logger.error(f"Failed to save watch {uuid}: {e}")
                raise Exception(
                    f"Migration failed: Could not save watch {uuid}. "
                    f"url-watches.json remains intact, safe to retry. Error: {e}"
                )

        logger.critical(f"Phase 1 complete: Saved {saved_count} watches")

        # Phase 2: Verify all files exist
        logger.critical("Phase 2/4: Verifying all watch.json files were created...")

        missing = []
        for uuid in self.data['watching'].keys():
            watch_json = os.path.join(self.datastore_path, uuid, "watch.json")
            if not os.path.isfile(watch_json):
                missing.append(uuid)

        if missing:
            raise Exception(
                f"Migration failed: {len(missing)} watch files missing: {missing[:5]}... "
                f"url-watches.json remains intact, safe to retry."
            )

        logger.critical(f"Phase 2 complete: Verified {watch_count} watch files")

        # Phase 3: Create new settings file
        logger.critical("Phase 3/4: Creating changedetection.json...")

        try:
            self._save_settings()
        except Exception as e:
            logger.error(f"Failed to create changedetection.json: {e}")
            raise Exception(
                f"Migration failed: Could not create changedetection.json. "
                f"url-watches.json remains intact, safe to retry. Error: {e}"
            )

View on GitHub (pinned to 5d9c7c6da7)

Solutions

  1. Check disk space and permissions, then simply restart the app — the migration is designed to be re-run
  2. Inspect the listed uuid directories: create/restore the missing watch.json or remove those uuids from url-watches.json if the watches are disposable
  3. Disable aggressive sync/AV on the datastore volume
  4. Back up the whole datastore dir (and url-watches.json) before retrying
Defensive patterns

Strategy: retry

Validate before calling

# pre-migration: verify the datastore dir is writable and has space
import shutil
assert shutil.disk_usage(datastore_path).free > len(watching) * 64 * 1024  # rough headroom

Try / catch

try:
    update_26(datastore)
except Exception as e:
    if 'watch files missing' in str(e):
        time.sleep(30); restart_app()  # migration is idempotent and safe to retry

Prevention

When it happens

Trigger: Phase 1 reported success (or was interrupted) but one or more watch.json files are absent on disk — typically a process killed mid-migration, disk full causing silent write failures, or filesystem sync issues on network volumes.

Common situations: Container OOM-killed or restarted during a large migration; NFS/bind-mount caching hiding freshly written files; antivirus or sync tools (dropbox-style) deleting/moving new files; disk-full during Phase 1.

Related errors


AI-assisted analysis of dgtlmoon/changedetection.io@5d9c7c6da7 (2026-08-27). Data as JSON: /api/errors/f484034737beb88e. Report an issue: GitHub.