{"record":{"id":"dc93397491c2e988","repo":"langflow-ai/langflow","slug":"error-source-top-level-value-must-be-an-object","errorCode":null,"errorMessage":"error: {source} top-level value must be an object","messagePattern":"error: (.+?) top-level value must be an object","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"scripts/migrate/check_migration_append_only.py","lineNumber":96,"sourceCode":"        # \"no baseline\" and return None.\n        return None\n    return completed.stdout\n\n\ndef _parse(raw: str, *, source: str) -> tuple[list[dict], list[dict]]:\n    \"\"\"Return ``(entries, ambiguous_bare_names)`` from a migration-table JSON.\n\n    Both lists default to empty when the field is absent so this script can\n    compare across baselines that pre-date a given field.\n    \"\"\"\n    try:\n        data = json.loads(raw)\n    except json.JSONDecodeError as exc:\n        print(f\"error: invalid JSON in {source}: {exc}\", file=sys.stderr)\n        raise SystemExit(2) from exc\n    if not isinstance(data, dict):\n        print(f\"error: {source} top-level value must be an object\", file=sys.stderr)\n        raise SystemExit(2)\n    entries = data.get(\"entries\", [])\n    if not isinstance(entries, list):\n        print(f\"error: {source} entries field must be a list\", file=sys.stderr)\n        raise SystemExit(2)\n    ambig = data.get(\"ambiguous_bare_names\", [])\n    if not isinstance(ambig, list):\n        print(f\"error: {source} ambiguous_bare_names field must be a list\", file=sys.stderr)\n        raise SystemExit(2)\n    return entries, ambig\n\n\ndef _compare(baseline: list[dict], current: list[dict]) -> list[str]:\n    \"\"\"Return human-readable violations; empty list means clean.\"\"\"\n    violations: list[str] = []\n    current_by_key: dict[tuple[str, str], dict] = {}\n    for entry in current:\n        try:\n            key = _entry_key(entry)","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/scripts/migrate/check_migration_append_only.py#L78-L114","documentation":"Printed and raised (exit code 2) by _parse in check_migration_append_only.py when the migration-table JSON parses successfully but its top-level value is not an object — e.g. the file is a JSON array or a bare string/number. The schema requires an object with `entries` (and optional `ambiguous_bare_names`) lists, so the script refuses to compare.","triggerScenarios":"Rewriting the migration table as a bare array of entries ([{...},{...}]) or wrapping it in a string; json.loads succeeds, the isinstance(data, dict) check fails, and the script exits 2.","commonSituations":"Refactoring the table format without updating the script's expectation; generating the file with a tool that emits top-level arrays; partially applied format migrations.","solutions":["Wrap the content in an object with the required keys: {\"entries\": [...], \"ambiguous_bare_names\": [...]}","Confirm `entries` and (if present) `ambiguous_bare_names` are lists, or the next validation will also fail","If the format change is intentional, update _parse and downstream comparison logic in the same commit"],"exampleFix":"# before\n[\n  {\"name\": \"0001_initial\", \"digest\": \"abc\"}\n]\n\n# after\n{\n  \"entries\": [\n    {\"name\": \"0001_initial\", \"digest\": \"abc\"}\n  ],\n  \"ambiguous_bare_names\": []\n}","handlingStrategy":"type-guard","validationCode":"import json\ndata = json.loads(raw)\nif not isinstance(data, dict) or not isinstance(data.get(\"entries\", []), list):\n    raise ValueError(\"migration table must be an object with an `entries` list\")","typeGuard":"def is_migration_table(data: object) -> bool:\n    return (\n        isinstance(data, dict)\n        and isinstance(data.get(\"entries\", []), list)\n        and isinstance(data.get(\"ambiguous_bare_names\", []), list)\n    )","tryCatchPattern":"# the script exits 2; catch at the CI step level\ndata = json.loads(raw)\nif not isinstance(data, dict):\n    print(f\"expected object, got {type(data).__name__}\"); sys.exit(2)","preventionTips":["Keep the migration-table schema fixed: top-level object with entries/ambiguous_bare_names lists","Generate the file from typed tooling rather than by hand","If changing the format, update check_migration_append_only.py in the same commit"],"tags":["python","json","migrations","tooling","schema"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}