Repair malformed JSON from LLMs, APIs, logs, and user input in Python.
This report presents the forensic synthetic code analysis of mangiucugna/json_repair, a Python project with 5,058 GitHub stars. SynthScan v2.0 examined 12,893 lines of code across 80 source files, recording 377 pattern matches distributed across 11 syntactic categories. The overall adjusted score of 33.0 places this repository in the Strong AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
Longitudinal tracking requires multiple scan runs. Once this repository is re-scanned after new commits land, this chart will visualise how the synthetic code signal evolves over time — enabling you to detect whether AI authorship is growing, stabilising, or being actively corrected by human engineers.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 377 distinct pattern matches across 11 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_parse_comment.py | 24 | def test_line_comment_brackets_do_not_trigger_empty_object_array_fallback(): | CODE |
| LOW⚡ | tests/test_parse_comment.py | 31 | def test_block_comment_brackets_do_not_trigger_empty_object_array_fallback(): | CODE |
| LOW⚡ | tests/test_parse_comment.py | 38 | def test_line_comment_brackets_do_not_close_array_items(): | CODE |
| LOW | tests/test_parse_comment.py | 63 | def test_parse_many_top_level_comments_without_recursion_error(): | STRING |
| LOW | tests/test_docs_app_schema.py | 15 | def test_docs_api_without_schema_keeps_existing_behavior(client): | CODE |
| LOW | tests/test_docs_app_schema.py | 26 | def test_docs_api_schema_null_is_treated_as_missing(client): | CODE |
| LOW | tests/test_docs_app_schema.py | 37 | def test_docs_api_schema_guides_coercion(client): | CODE |
| LOW | tests/test_docs_app_schema.py | 58 | def test_docs_api_rejects_invalid_schema_type(client): | CODE |
| LOW | tests/test_docs_app_schema.py | 85 | def test_docs_api_rejects_circular_schema_ref(client): | CODE |
| LOW⚡ | tests/test_docs_app_schema.py | 103 | def test_docs_api_rejects_invalid_schema_repair_mode_type(client): | CODE |
| LOW⚡ | tests/test_docs_app_schema.py | 113 | def test_docs_api_rejects_invalid_schema_repair_mode_value(client): | CODE |
| LOW⚡ | tests/test_docs_app_schema.py | 123 | def test_docs_api_rejects_salvage_mode_without_schema(client): | CODE |
| LOW⚡ | tests/test_docs_app_schema.py | 133 | def test_docs_api_salvage_mode_drops_invalid_array_items(client): | CODE |
| LOW | tests/test_parse_number.py | 11 | def test_parse_number_edge_cases(): | CODE |
| LOW⚡ | tests/test_json_repair.py | 28 | def test_valid_json_fast_path_does_not_initialize_repair_parser(monkeypatch): | CODE |
| LOW⚡ | tests/test_json_repair.py | 29 | def fail_parser_initialization(*_args, **_kwargs): | CODE |
| LOW⚡ | tests/test_json_repair.py | 37 | def test_prefixed_valid_json_uses_value_fast_path_when_json_loads_is_skipped(monkeypatch): | CODE |
| LOW | tests/test_json_repair.py | 62 | def test_prefixed_valid_json_with_trailing_text_uses_value_fast_path(monkeypatch): | CODE |
| LOW | tests/test_json_repair.py | 73 | def test_prefixed_invalid_json_falls_back_to_repair_parser(): | CODE |
| LOW | tests/test_json_repair.py | 92 | def test_top_level_separator_detects_pending_comma(): | CODE |
| LOW | tests/test_json_repair.py | 98 | def test_parenthesized_prose_does_not_hijack_fenced_json(): | CODE |
| LOW | tests/test_json_repair.py | 115 | def test_numbered_prose_line_does_not_hijack_fenced_json(): | CODE |
| LOW | tests/test_json_repair.py | 132 | def test_parenthesized_tuple_still_parses_when_it_is_the_fenced_json_payload(): | CODE |
| LOW | tests/test_json_repair.py | 145 | def test_repair_json_with_objects(): | CODE |
| LOW⚡ | tests/test_json_repair.py | 235 | def test_repair_json_skip_json_loads(): | CODE |
| LOW | tests/test_json_repair.py | 260 | def _find_real_recursion_payload() -> str: | CODE |
| LOW | tests/test_json_repair.py | 275 | def test_repair_json_normalizes_real_parser_recursion_error(): | CODE |
| LOW | tests/test_repair_json_from_file.py | 9 | def test_load_repairs_from_current_file_position(): | CODE |
| LOW | tests/test_repair_json_from_file.py | 20 | def test_repair_json_from_file(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 6 | def test_strict_rejects_multiple_top_level_values(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 11 | def test_strict_rejects_comma_separated_same_shape_top_level_objects(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 16 | def test_strict_rejects_adjacent_same_shape_top_level_objects(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 21 | def test_strict_rejects_adjacent_same_shape_top_level_arrays(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 27 | def test_strict_rejects_falsy_top_level_values(payload): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 32 | def test_strict_duplicate_keys_inside_array(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 38 | def test_strict_rejects_empty_keys(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 44 | def test_strict_requires_colon_between_key_and_value(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 49 | def test_strict_rejects_empty_values(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 55 | def test_strict_rejects_empty_object_with_extra_characters(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 60 | def test_strict_rejects_empty_escaped_object_with_extra_characters(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 65 | def test_strict_detects_immediate_doubled_quotes(): | CODE |
| LOW⚡ | tests/test_strict_mode.py | 70 | def test_strict_detects_doubled_quotes_followed_by_string(): | CODE |
| LOW | tests/test_parse_array.py | 12 | def test_parse_array_edge_cases(): | CODE |
| LOW⚡ | tests/test_parse_array.py | 53 | def test_parse_array_python_tuple_literals(): | CODE |
| LOW⚡ | tests/test_parse_array.py | 60 | def test_parse_array_parenthesized_scalar_keeps_scalar_shape(): | CODE |
| LOW⚡ | tests/test_parse_array.py | 67 | def test_parse_array_mismatched_parenthesis_still_logs_missing_bracket(): | CODE |
| LOW⚡ | tests/test_parse_array.py | 74 | def test_parenthesized_tuple_classifier_handles_nested_delimiters_and_missing_close(): | CODE |
| LOW⚡ | tests/test_parse_array.py | 82 | def test_top_level_parenthesized_value_gate_rejects_prose_and_accepts_standalone_jsonish_values(): | CODE |
| LOW⚡ | tests/test_parse_array.py | 96 | def test_parse_array_missing_quotes(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 37 | def parse_array_direct_with_mode(raw, schema, mode): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 45 | def test_parse_object_schema_true_false_and_non_object(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 52 | def test_parse_object_schema_property_fallbacks_and_stray_colon(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 62 | def test_parse_object_schema_invalid_property_schema_raises(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 68 | def test_parse_object_schema_invalid_pattern_schema_raises(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 74 | def test_parse_object_schema_invalid_pattern_extra_schema_raises(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 83 | def test_parse_array_schema_missing_object_brace(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 158 | def test_parse_object_schema_empty_object_falls_back_to_array(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 163 | def test_parse_object_schema_salvage_set_literal_keeps_non_string_members_as_array(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 168 | def test_parse_array_schema_true_false_and_non_array(): | CODE |
| LOW⚡ | tests/test_schema_parser_paths.py | 175 | def test_parse_array_schema_items_and_additional_items(): | CODE |
| 238 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/test_json_repair.py | 149 | assert repair_json('{"key": true, "key2": false, "key3": null}', return_objects=True) == { | CODE |
| HIGH⚡ | tests/test_json_repair.py | 237 | repair_json('{"key": true, "key2": false, "key3": null}', skip_json_loads=True) | CODE |
| HIGH⚡ | tests/test_json_repair.py | 238 | == '{"key": true, "key2": false, "key3": null}' | CODE |
| HIGH⚡ | tests/test_json_repair.py | 241 | '{"key": true, "key2": false, "key3": null}', | CODE |
| HIGH | tests/test_parse_array.py | 21 | assert repair_json("[true, false, null, ...]") == "[true, false, null]" | CODE |
| HIGH | tests/test_parse_object.py | 12 | assert repair_json('{ "key": value, "key2": 1 "key3": null }', return_objects=True) == { | CODE |
| HIGH⚡ | tests/test_parse_string.py | 46 | repair_json("{'key': 'string', 'key2': false, \"key3\": null, \"key4\": unquoted}") | CODE |
| HIGH⚡ | tests/test_parse_string.py | 47 | == '{"key": "string", "key2": false, "key3": null, "key4": "unquoted"}' | CODE |
| HIGH⚡ | tests/test_parse_string.py | 386 | assert repair_json(' {"key": true, "key2": false, "key3": null}') == '{"key": true, "key2": false, "key3": null}' | STRING |
| HIGH⚡ | tests/test_parse_string.py | 387 | assert repair_json('{"key": TRUE, "key2": FALSE, "key3": Null} ') == '{"key": true, "key2": false, "key3": null}' | STRING |
| HIGH | tests/test_schema_guided_parse.py | 605 | == '{"a": null, "b": null}' | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | examples/pydantic_schema.py | 3 | CODE | |
| LOW | examples/stream_stable.py | 3 | CODE | |
| LOW | examples/repair_llm_output.py | 3 | CODE | |
| LOW | examples/chinese_llm_output.py | 3 | CODE | |
| LOW | examples/fastapi_app.py | 3 | CODE | |
| LOW | src/json_repair/parse_array.py | 9 | CODE | |
| LOW | src/json_repair/parse_comment.py | 7 | CODE | |
| LOW | src/json_repair/parser_parenthesized.py | 6 | CODE | |
| LOW | src/json_repair/schema_repair.py | 1 | CODE | |
| LOW | src/json_repair/parse_string.py | 11 | CODE | |
| LOW | src/json_repair/__init__.py | 1 | CODE | |
| LOW | src/json_repair/__init__.py | 1 | CODE | |
| LOW | src/json_repair/__init__.py | 1 | CODE | |
| LOW | src/json_repair/__init__.py | 1 | CODE | |
| LOW | src/json_repair/__init__.py | 2 | CODE | |
| LOW | src/json_repair/parse_object.py | 9 | CODE | |
| LOW | src/json_repair/parse_object.py | 10 | CODE | |
| LOW | src/json_repair/parse_number.py | 10 | CODE | |
| LOW | src/json_repair/parser_schema.py | 1 | CODE | |
| LOW | …on_repair/parse_string_helpers/parse_json_llm_block.py | 6 | CODE | |
| LOW | …on_repair/parse_string_helpers/object_value_context.py | 7 | CODE | |
| LOW | …n_repair/parse_string_helpers/parse_boolean_or_null.py | 4 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/json_repair/parse_array.py | 12 | CODE | |
| LOW | src/json_repair/parse_array.py | 41 | CODE | |
| LOW | src/json_repair/parse_comment.py | 10 | CODE | |
| LOW | src/json_repair/parser_parenthesized.py | 9 | CODE | |
| LOW | src/json_repair/parser_parenthesized.py | 82 | CODE | |
| LOW | src/json_repair/schema_repair.py | 45 | CODE | |
| LOW | src/json_repair/schema_repair.py | 91 | CODE | |
| LOW | src/json_repair/schema_repair.py | 365 | CODE | |
| LOW | src/json_repair/parse_string.py | 56 | CODE | |
| LOW | src/json_repair/parse_string.py | 116 | CODE | |
| LOW | src/json_repair/parse_string.py | 143 | CODE | |
| LOW | src/json_repair/parse_string.py | 185 | CODE | |
| LOW | src/json_repair/parse_string.py | 433 | CODE | |
| LOW | src/json_repair/parse_string.py | 463 | CODE | |
| LOW | src/json_repair/parse_string.py | 535 | CODE | |
| LOW | src/json_repair/parse_string.py | 659 | CODE | |
| LOW | src/json_repair/json_repair.py | 100 | CODE | |
| LOW | src/json_repair/parse_object.py | 82 | CODE | |
| LOW | src/json_repair/parse_object.py | 132 | CODE | |
| LOW | src/json_repair/parse_object.py | 181 | CODE | |
| LOW | src/json_repair/parse_object.py | 379 | CODE | |
| LOW | src/json_repair/json_parser.py | 112 | CODE | |
| LOW | src/json_repair/utils/pattern_properties.py | 7 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | src/json_repair/json_repair.py | 425 | print("Error: Inline mode requires a filename", file=sys.stderr) | CODE |
| MEDIUM⚡ | src/json_repair/json_repair.py | 429 | print("Error: You cannot pass both --inline and --output", file=sys.stderr) | CODE |
| MEDIUM⚡ | src/json_repair/json_repair.py | 433 | print("Error: You cannot pass both --schema and --schema-model", file=sys.stderr) | CODE |
| MEDIUM⚡ | src/json_repair/json_repair.py | 437 | print("Error: --strict cannot be used with --schema or --schema-model", file=sys.stderr) | CODE |
| MEDIUM⚡ | src/json_repair/json_repair.py | 440 | print("Error: --schema-repair-mode salvage requires --schema or --schema-model", file=sys.stderr) | CODE |
| MEDIUM | src/json_repair/json_repair.py | 477 | print(f"Error: {e!s}", file=sys.stderr) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_repair_json_from_file.py | 429 | # Create a temporary file | COMMENT |
| MEDIUM | tests/test_repair_json_from_file.py | 497 | # Create a temporary file | COMMENT |
| MEDIUM | tests/test_repair_json_cli.py | 14 | # Create a temporary file | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_parse_array.py | 99 | repair_json('{"bad_one":["Lorem Ipsum", "consectetur" comment" ], "good_one":[ "elit", "sed", "tempor"]}') | CODE |
| LOW⚡ | tests/test_parse_array.py | 100 | == '{"bad_one": ["Lorem Ipsum", "consectetur", "comment"], "good_one": ["elit", "sed", "tempor"]}' | CODE |
| LOW⚡ | tests/test_parse_array.py | 103 | repair_json('{"bad_one": ["Lorem Ipsum","consectetur" comment],"good_one": ["elit","sed","tempor"]}') | CODE |
| LOW⚡ | tests/test_parse_array.py | 104 | == '{"bad_one": ["Lorem Ipsum", "consectetur", "comment"], "good_one": ["elit", "sed", "tempor"]}' | CODE |
| LOW | tests/test_parse_string.py | 82 | repair_json('{"key": "lorem ipsum ... "sic " tamet. ...}') == '{"key": "lorem ipsum ... \\"sic \\" tamet. ..."}' | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/json_repair/json_repair.py | 339 | Command-line interface for repairing and parsing JSON files. Args: inline_args (Optional[List[str]]): | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/json_repair/json_repair.py | 37 | CODE | |
| LOW | src/json_repair/json_repair.py | 53 | CODE | |
| LOW | src/json_repair/json_repair.py | 69 | CODE | |
| LOW | src/json_repair/json_repair.py | 85 | CODE | |
| LOW | src/json_repair/json_repair.py | 100 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pyproject.toml | 81 | where = ["src"] | COMMENT |
| LOW | pyproject.toml | 101 | # Flake8-implicit-str-concat - ISC | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/json_repair/__init__.py | 4 | __all__ = ["JSONReturnType", "from_file", "load", "loads", "repair_json"] | CODE |