{"record":{"id":"08abd6353426b726","repo":"deepset-ai/haystack","slug":"invalid-pipeline-snapshot-from-file-path-str-e","errorCode":null,"errorMessage":"Invalid pipeline snapshot from {file_path}: {str(e)}","messagePattern":"Invalid pipeline snapshot from (.+?): (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"haystack/core/pipeline/breakpoint.py","lineNumber":125,"sourceCode":"        Dict containing the loaded pipeline_snapshot.\n    \"\"\"\n\n    file_path = Path(file_path)\n\n    try:\n        with open(file_path, encoding=\"utf-8\") as f:\n            pipeline_snapshot_dict = json.load(f)\n    except FileNotFoundError as e:\n        raise FileNotFoundError(f\"File not found: {file_path}\") from e\n    except json.JSONDecodeError as e:\n        raise json.JSONDecodeError(f\"Invalid JSON file {file_path}: {str(e)}\", e.doc, e.pos) from e\n    except OSError as e:\n        raise OSError(f\"Error reading {file_path}: {str(e)}\") from e\n\n    try:\n        pipeline_snapshot = PipelineSnapshot.from_dict(pipeline_snapshot_dict)\n    except ValueError as e:\n        raise ValueError(f\"Invalid pipeline snapshot from {file_path}: {str(e)}\") from e\n\n    logger.info(\"Successfully loaded the pipeline snapshot from: {file_path}\", file_path=file_path)\n    return pipeline_snapshot\n\n\ndef _save_pipeline_snapshot(\n    pipeline_snapshot: PipelineSnapshot,\n    raise_on_failure: bool = True,\n    snapshot_callback: SnapshotCallback | None = None,\n) -> str | None:\n    \"\"\"\n    Save the pipeline snapshot dictionary to a JSON file, or invoke a custom callback.\n\n    If a `snapshot_callback` is provided, it will be called with the pipeline snapshot instead of saving to a file.\n    This allows users to customize how snapshots are handled (e.g., saving to a database, sending to a remote service).\n\n    When no callback is provided, the default behavior saves to a JSON file:\n    - The filename is generated based on the component name, visit count, and timestamp.","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/core/pipeline/breakpoint.py#L107-L143","documentation":"load_pipeline_snapshot wraps ValueError raised by PipelineSnapshot.from_dict to indicate the JSON file exists but its content is not a valid pipeline snapshot. Haystack throws this when deserializing a snapshot file fails schema/type validation during resume. The original ValueError message is preserved in the new message.","triggerScenarios":"Calling load_pipeline_snapshot(path) on a file whose parsed dict is missing required PipelineSnapshot keys (pipeline, state, etc.), has wrong types, or was produced by an incompatible haystack version.","commonSituations":"Hand-edited or truncated snapshot files; snapshots saved by a different haystack version with a changed schema; passing a JSON file that is valid JSON but not a pipeline snapshot (e.g. a tool/sandbox config or breakpoint dump).","solutions":["Inspect the inner message for the exact from_dict failure (missing key / bad type) and fix the snapshot file accordingly","Regenerate the snapshot by re-running the pipeline with PipelineDebugger/quit.save or the resume callback so the file matches the current schema","Verify the file was written by the same haystack version that is resuming; upgrade/downgrade so versions match","Confirm you passed the snapshot JSON file path, not a YAML pipeline file or breakpoint-only file"],"exampleFix":"// before\nsnapshot = load_pipeline_snapshot(\"hand_edited.json\")  # ValueError\n// after\nimport json\ndata = json.load(open(\"snapshot.json\"))\nassert {\"pipeline\", \"runs\", \"network_status\"} <= set(data)  # sanity check\nsnapshot = load_pipeline_snapshot(\"snapshot.json\")","handlingStrategy":"validation","validationCode":"import json\n\ndef can_load_snapshot(path):\n    try:\n        data = json.load(open(path))\n    except Exception:\n        return False\n    return isinstance(data, dict) and \"pipeline\" in data","typeGuard":"def is_snapshot_dict(obj):\n    return isinstance(obj, dict) and isinstance(obj.get(\"pipeline\"), dict)","tryCatchPattern":"try:\n    snapshot = load_pipeline_snapshot(path)\nexcept (OSError, ValueError) as e:\n    logger.error(\"Cannot resume: %s\", e)\n    # re-save the snapshot or abort resume","preventionTips":["Never hand-edit snapshot files; regenerate them","Pin the same haystack version for save and resume","Validate JSON loads before calling load_pipeline_snapshot","Keep snapshot files out of tools that rewrite/pretty-print them"],"tags":["pipeline","resume","deserialization","validation"],"backgroundTag":"snapshot-deserialization-failed","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}