{"record":{"id":"02a687e411b4655c","repo":"langgenius/dify","slug":"label-json-is-invalid-exc-msg","errorCode":null,"errorMessage":"{label} JSON is invalid: {exc.msg}","messagePattern":"(.+?) JSON is invalid: (.+?)","errorType":"exception","errorClass":"MigrationDataError","httpStatus":null,"severity":"error","filePath":"api/commands/data_migration.py","lineNumber":273,"sourceCode":"            conflict_strategy=conflict_strategy,\n            output_file=output_file,\n        )\n        with session_factory.create_session() as session:\n            result = MigrationExportService().export(selection, session=session)\n        MigrationPackageService().save_package(result.package, output_file, overwrite=overwrite)\n        click.echo(click.style(f\"Output written to {output_file}\", fg=\"green\"))\n        _print_wizard_step(\"Report\")\n        _render_report(result.report_items, context=_with_output_path(result.report_context, output_file))\n    except MigrationDataError as exc:\n        raise click.ClickException(str(exc)) from exc\n\n\ndef _load_json_object(path: str, label: str) -> dict[str, Any]:\n    try:\n        with Path(path).open(encoding=\"utf-8\") as file:\n            raw = json.load(file)\n    except json.JSONDecodeError as exc:\n        raise MigrationDataError(f\"{label} JSON is invalid: {exc.msg}\") from exc\n    if not isinstance(raw, dict):\n        raise MigrationDataError(f\"{label} JSON must be an object.\")\n    return raw\n\n\ndef _require_options(*options: tuple[str, object | None]) -> None:\n    missing_options = [name for name, value in options if value is None]\n    if missing_options:\n        raise click.UsageError(f\"Missing option(s): {', '.join(missing_options)}.\")\n\n\ndef _build_options_override(\n    package_options: ImportOptions,\n    *,\n    id_strategy: str | None,\n    conflict_strategy: str | None,\n    create_app_api_token_on_import: bool | None,\n) -> ImportOptions | None:","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/commands/data_migration.py#L255-L291","documentation":"MigrationDataError raised by _load_json_object when json.load on the given path raises JSONDecodeError. The label (e.g. 'package manifest', 'selection') identifies which input file failed, and exc.msg carries the parser's position/message. The wizard's outer handler converts MigrationDataError into a click.ClickException for CLI display.","triggerScenarios":"Triggered when the --package/--selection (or other labeled) JSON file passed to the data-migration wizard is syntactically invalid: trailing commas, unquoted keys, truncated download, BOM/encoding issues, or empty file.","commonSituations":"The migration package file was partially downloaded or corrupted, edited by hand with a syntax error, or saved with a non-UTF-8 encoding. The label tells you which file to re-inspect.","solutions":["Run the file through a JSON linter (e.g. `python -m json.tool path/to/file.json`) to locate the syntax error.","Re-export or re-download the migration package to rule out truncation.","Ensure the file is UTF-8 encoded without a leading BOM.","Use the label in the message to identify which CLI argument's file is broken."],"exampleFix":"# before - file has trailing comma\n{\n  \"source_tenant\": {...},\n}\n\n# after\n{\n  \"source_tenant\": {}\n}","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\ndef validate_json_file(path: str) -> dict:\n    text = Path(path).read_text(encoding=\"utf-8\")\n    try:\n        return json.loads(text)\n    except json.JSONDecodeError:\n        raise SystemExit(f\"{path} is not valid JSON; fix with a linter first\")","typeGuard":"def is_valid_json_object(path: str) -> bool:\n    try:\n        with Path(path).open(encoding=\"utf-8\") as f:\n            return isinstance(json.load(f), dict)\n    except (json.JSONDecodeError, OSError):\n        return False","tryCatchPattern":"try:\n    payload = _load_json_object(path, \"package\")\nexcept MigrationDataError as exc:\n    click.echo(f\"Input file rejected: {exc}\", err=True)\n    raise click.Abort()","preventionTips":["Run `python -m json.tool <file>` on exported packages before importing.","Re-download packages that may have been truncated in transit.","Save packages with UTF-8 encoding and no BOM.","Treat the {label} in the message as the identifier of which CLI arg's file failed."],"tags":["backend","cli","data-migration","json","validation"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}