Elixir Consulting Group · Blog

Published October26,2026 · Independent practical guide

Check Duplicate JSON Names Before an AI Handoff

A JSON handoff can look orderly while containing the same object name twice. A draft might contain a status field marked proposed and another status field marked approved in the same object. If a receiving parser keeps only one value, the conflict can disappear from the parsed result. Looking at that result afterward does not reveal which duplicate text was discarded. Check the original authorized text before treating a parsed object as a faithful representation of the handoff.

This guide explains that narrow problem with original fictional files and a local read-only checker. No AI model is called, and the files are authored teaching cases rather than observed model outputs, client records or operating approvals. Passing the checker means its defined input checks passed. It does not establish that a statement is true, that a proposed procedure is approved, that a schema is satisfied or that a payload is safe to execute. Those are separate questions with separate evidence and controls.

Understand what can be lost before the handoff is reviewed

Imagine a fictional draft object with a status name appearing twice, first with proposed and later with approved. A reviewer who sees both entries can identify a conflict. A reviewer who receives only a dictionary containing the later value may never see the earlier entry. This is a reason to inspect the source representation, not evidence that any particular AI system generated the conflict. The example was deliberately written to make the parsing issue visible.

RFC8259 says object names should be unique and describes differing behavior when they are not. Some receiving software may retain a later value, while other software may reject the input or handle the repeated entries differently. Do not assume that a file accepted by one component will be interpreted identically everywhere. A handoff needs a defined expectation about the representation before a person relies on its contents.

The Python json documentation describes its default handling of repeated names and an object-pairs hook that can change the behavior. The supplied checker uses such a hook to reject a duplicate while the pairs are still available. Its purpose is to prevent this particular kind of loss inside the teaching workflow. It does not recover information already discarded by an earlier parser, and it does not establish how another application's parser is configured.

Distinguish duplicate names from ordinary repeated values

Two fields can legitimately contain the same value. A fictional record could have both requested_owner and review_owner set to unassigned. Those are different names, so equal values do not make them duplicate members. Conversely, two occurrences of the name status in the same object are duplicates even if both values happen to be proposed. The check concerns object names and their scope, not whether the repeated value appears harmless.

The same name can also occur in different objects. A draft object and a separate review object might each contain status. They have different scopes. A tool that simply searches the whole file for repeated words would confuse these cases. The supplied checker examines the pairs belonging to each object independently, including objects nested inside arrays. That makes the accepted and rejected examples reproducible without pretending a text search is a JSON parser.

Arrays introduce another separate question. Repeated array elements are not duplicate object names. A list might deliberately contain repeated values, or it might contain unintended duplicate records. This checker does not decide which interpretation is correct. If the task requires unique record identifiers, ordering rules or a fixed number of steps, define and test those requirements separately. A successful object-name check should not be reported as proof that the whole dataset has no duplicates.

Use the original text rather than a reconstructed dictionary

Keep the authorized original file available through the appropriate local process. If an application has already parsed a duplicate-containing object and then serialized the resulting dictionary, the earlier duplicate may be gone. Running this checker on the reconstructed file cannot reveal the lost member. That does not make the original conflict resolved. It means the new representation no longer contains the evidence needed for this particular check.

In a practical AI-assisted drafting workflow, identify which file is the actual output text being reviewed and which file is a later export or transformation. Do not assume that a file extension proves provenance. A saved response, a manually edited version and a system export can differ even when their filenames look similar. Keep the version reference with the review so that the person making a later comparison knows what was actually checked.

The teaching utility does not fetch a response, access an account or create an output file. It reads one local path and prints a small report only after the checks finish. The report contains counts rather than the input values or member names. That limited behavior makes the exercise easier to inspect, but it is not an authorization system for handling real records. Use only information you are permitted to process and keep any actual data within the approved environment.

Reproduce the accepted fixture before testing a rejection

The original accepted fixture contains a case identifier, a nested draft object, an array with one step object and a numerical quantity. There are three objects in total: the root, the draft and the object inside the step array. The root has four members, the draft has two and the step object has two, giving eight members across the file. The expected report therefore contains object_count three, member_count eight and top_level_member_count four.

Run the downloaded script against the downloaded accepted fixture in a local folder and compare the resulting JSON with the supplied expected report. Use a maintained Python installation; the release checks were run with Python3.12. The fixture is not a real procedure and its approval-related value is not an actual decision. The count result verifies the stated structure of this authored example, not the truth of any text inside it.

Next run the script against the deliberately duplicated fixture. It contains two status members inside one nested object. The expected behavior is a nonzero exit status, an explanatory message on standard error and no success report on standard output. The program does not choose which status to keep and does not rewrite the file. Inspect the original local text to understand the rejection rather than treating an automatically selected value as a resolved decision.

Read the hook as a small, defined check

For each object, the hook receives its member pairs before constructing the returned dictionary. It starts with an empty result, visits the names in that object and stops if a name has already been added. If no duplicate is found, it returns the dictionary and updates the counts used in the report. Nested objects are also processed through the hook. The report counts their members as well as the root members, while keeping the root member count separate.

The comparison operates on the decoded names. An escaped spelling that decodes to status and a literal status in the same object refer to the same Python string and are rejected as a duplicate. Different case spellings remain different strings. The checker does not normalize accents, fold case or map application aliases. If the receiving application later treats distinct names as equivalent, that is another compatibility question which this program does not resolve.

Do not generalize the implementation into a complete Unicode or JSON interoperability validator. The script does not inspect every possible string-content issue or prove compatibility with every downstream numeric representation. Its report deliberately says defined checks passed. Read that phrase literally. It records a bounded result for one file under the supplied program, not a broad certificate that an entire handoff can be trusted by every component or used without further review.

Separate the chosen input limits from the JSON standard

The checker accepts at most one mebibyte of input, read as a limited byte sequence from one local file. That size is a teaching choice, not a universal JSON maximum. It decodes the bytes as UTF-8 and expects a single complete JSON text with a top-level object. A top-level array or scalar is rejected by this tool even though JSON itself can represent other top-level values. State the subset when describing a result.

The decoder rejects malformed syntax and the script rejects the non-JSON constants NaN, Infinity and negative Infinity through a callback. It uses decimal parsing for number tokens so a large exponent is not silently converted to an ordinary floating-point infinity for the report. No numerical values are returned to the caller. This is still not a claim of unrestricted numeric interoperability; a later consumer may have different ranges, precision or field requirements.

The program also has the limits of its runtime and libraries. Deeply nested input may be rejected through a recursion error; the script does not promise a particular supported nesting depth. Its byte cap does not make it a sandbox or a complete defense against hostile files. Use the original supplied fixtures for the exercise and follow an appropriate engineering process for any production parser. The guide makes no recommendation to expose this local teaching script as an untrusted public upload service.

Keep syntax, schema, meaning and authority separate

A file can pass the defined checks while omitting a required field, using an unexpected name or placing a string where an application expects a number. Those are schema or application-contract questions. This checker does not have a business schema and does not enforce one. After the representation question is addressed, compare the payload with the actual agreed field definitions and constraints using an appropriate separate validation step.

A file can also match a schema while making a false statement. A status string might use an allowed spelling without reflecting a real approval. A quantity might have the expected type while referring to the wrong item or unit. The existing AI-table and procedure-review guides address related meaning questions. Keep their conclusions separate from the parser result. A well-formed container does not establish the correctness of the operating proposal it carries.

Authority is a further question. A draft that says approved is not evidence that the responsible person has approved it. Confirm the actual source of the decision through the established process before any action that requires it. The teaching checker cannot contact that person, inspect a workflow or determine permissions. It makes no model, network, messaging or execution calls and changes no operating system or business record beyond printing its local report.

Resolve a rejection by finding the source of the conflict

When a duplicate is found, stop the handoff at that defined check and inspect the authorized original. Ask whether the repeated entry came from a manual edit, a merge, a conversion or another source. Those are possible investigation questions, not conclusions supplied by the checker. The deliberately duplicated fixture has a known cause because it was authored for the lesson. A real file requires its own evidence rather than a story borrowed from the teaching example.

Do not silently delete the earlier field or keep the later field as a universal repair rule. The two values might describe different intended concepts that need distinct agreed names, or one might be an incorrect edit. A responsible reviewer should resolve that meaning with the appropriate source. Record the corrected version and rerun the defined check. The script itself provides no automated repair, choice of authoritative value or claim that a conflict has been substantively resolved.

If the duplicate appeared after an earlier transformation, identify where the original evidence is available. A later dictionary export may be insufficient to reconstruct it. Keep that limitation explicit in the review rather than guessing the lost value. For the fictional exercise, both fixtures are supplied directly, so the reader can compare their text without depending on a hidden account, model history or proprietary tool. That controlled setup is what makes the example reproducible.

Document the result so another person can interpret it

A useful handoff note identifies the file version, the exact checker version, the defined limits and the result. It states which additional questions remain outside the check. For the accepted fixture, the counts can be reproduced and compared with the expected JSON. For the duplicate fixture, the rejection can be reproduced without editing the input. Neither result is a measured rate of model errors or evidence that a production workflow is robust.

Keep failures distinguishable from incomplete checks. A missing path, an unreadable file, an unsupported top-level value and a duplicate-name rejection all prevent a success report, but they do not mean the same thing. The utility deliberately gives a generic rejection message rather than exposing input values in diagnostic output. Inspect the local source and the stated limits to investigate. Do not report every rejected input as a duplicate or count file-access errors as model defects.

Only move to the next review step when the result supports it within the actual process. That might mean a separate schema check, a comparison against source documents or confirmation by a responsible owner. The local report does not trigger those steps automatically. It supplies one small piece of evidence about a representation problem. Useful AI assistance depends on preserving such boundaries, so a deterministic parser result does not grow into an unsupported claim about truth, safety or operational approval.

Interpret the count report without inferring a business result

The accepted fixture's object count includes the object inside the steps array. The array itself is not an object and therefore does not add one to object_count. Its single object element does. The quantity is a number token, not a member container, so its presence increases the root's member count but does not create another object. Distinguishing containers from members makes the expected three-object, eight-member report understandable without running the code first.

An empty object is another useful check. It has one object and zero members, and its top-level member count is zero. It passes the defined subset even though a real application might require a case identifier or other fields. That contrast exposes the boundary between this checker and a schema. A perfectly reproduced count report for an empty object supplies no evidence that the file is a complete operating request or an acceptable input to another system.

A different original test places an owner name in each of two objects within an array. It is accepted when each object's own names are unique. Moving both owner entries into the same object changes the result to rejection. The values can be identical in both versions; the scope of the names is what changes. These cases help a reader inspect why a repeated word is not always the same defect and why a flat search cannot substitute for the parser's object-level check.

Finally, changing the fictional quantity from an ordinary decimal to a large exponent does not make the checker evaluate a real amount or unit. The report still contains counts rather than a computed business value. A later application would need its own acceptable range, precision and meaning for that field. Keep that distinction in the handoff note: the local representation check can succeed while the value remains unsuitable for the receiving contract or unsupported by the source facts.

Frequently asked questions

Does ordinary JSON parsing always reject repeated names?

No. Receiving behavior can differ, and Python's documented default keeps the last value for a repeated name. The supplied script changes that behavior with an object-pairs hook and rejects duplicates before returning a dictionary. Use the actual receiving component's documented behavior for its own interpretation. This guide does not prove that every parser accepts or rejects the same input, and acceptance by one component does not establish a resolved handoff.

Are repeated names in different nested objects rejected?

Not simply because they appear in different objects. Each object is checked within its own scope. A draft object and a review object can each have a status member without creating a duplicate inside either one. A repeated status within one object is rejected even if the two values are equal. Repeated array records, case-folded aliases and application-specific uniqueness rules are separate issues that this tool does not validate.

Can the checker recover a value lost by an earlier parser?

No. If an earlier component discarded a duplicate and serialized only the surviving dictionary, the lost pair is not available in that reconstructed text. Check the authorized original representation when it is available and keep the limitation explicit when it is not. A clean result on a later export does not prove the original contained no conflict. The tool reads the supplied file and does not retrieve earlier versions or account histories.

Does a passing report mean the JSON matches our schema?

No. The script has no business schema. Its report covers the stated local input subset and duplicate-name behavior, not required fields, allowed status vocabulary, units, reference identifiers or other application constraints. Use an appropriate separate schema or contract check for those requirements, then review meaning and authority through their own processes. The original fixture's count report is evidence about its constructed structure, not an approval of its contents.

Will the script change or upload my file?

The supplied code reads one local file and prints a small count report after the checks finish. It has no output-file write, network, model or messaging call and does not attempt an automatic repair. Rejection produces no success JSON on standard output. The release checks compare input hashes before and after execution. These are statements about this supplied teaching program, not guarantees about another tool or a modified copy.

Is this a complete JSON conformance or security validator?

No. It is a deliberately bounded teaching checker with a chosen byte limit, UTF-8 input, top-level-object requirement and defined duplicate/constant handling. It does not implement every interoperability constraint, schema, Unicode policy, numeric consumer limit or protection needed for hostile inputs. Passing it cannot authorize execution or establish truth. Use a suitable engineering and review process for the actual system, and keep the local exercise's result within its stated scope.

Original practice files and reproduction

Two authored JSON fixtures, not observed model outputs or real operating records.

Use a maintained Python3.11+ installation. Release tests ran on Python3.12.14. In a local folder run:

python3 check_json_names.py accepted-fixture.json

Compare the count report with expected-report.json. Then run:

python3 check_json_names.py duplicate-fixture.json

Expected: exit2, a generic local rejection message on stderr, and no success JSON on stdout. Neither input is changed. No network/model/messaging/process-execution or output-file-write calls. The1MiB size limit and top-level-object requirement are chosen teaching constraints, not a full JSON-conformance or security policy.

Manually expected behavior for original fixtures
FixtureExpected
Accepted3 objects,8 total members,4 root members
DuplicateRejected; no success report

Primary sources and scope

Sources read October26,2026. Original teaching code and fictional examples, not code extracted from the RFC. AI-assisted website editorial content with manually expected utility checks; no client outcomes, measured model accuracy, named professional review, certification or institutional endorsement.

Related practical questions