Skip to content

Refuse a field name that is not a field - #116

Open
ramonski wants to merge 1 commit into
fix/single-valued-dx-uidreferencefrom
fix/refuse-unknown-fields
Open

ramonski wants to merge 1 commit into
fix/single-valued-dx-uidreferencefrom
fix/refuse-unknown-fields

Conversation

@ramonski

@ramonski ramonski commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Builds on #115, and has to: a name a Dexterity type kept from its Archetypes days must reach its field before unknown names can be refused, or every payload written against the documented API would be refused instead.

A name in a record that matches no field and no setter is dropped with a line in the log, and the request answers that the object has been created or updated.

Current behavior before PR

POST /create {"portal_type": "AnalysisProfile", ...,
              "Service": ["whatever"], "Nonsense": 42}

200 {"count": 1, "items": [{..., "services": []}]}

Both keys are gone and the caller is told all is well. This is how an afternoon goes missing: the typo was Service for services, a spec reported fifty-eight objects composed, and the profile it had just written stayed empty.

The code says so plainly:

            if success is False:
                logger.warning("update_object_with_data::skipping key=%r", k)
                continue

DexterityDataManager.set returns False when it finds neither a schema field nor a setter for the name.

Desired behavior after PR is merged

400 {"message": "No objects could be created: No field named 'Service' on
                 AnalysisProfile. Did you mean 'services'?", ...}

Without a field close enough to suggest, it says only what it knows:

400 {"message": "No objects could be created: No field named 'Nonsense' on
                 AnalysisProfile", ...}

The suggestion comes from difflib.get_close_matches over the object's own field names.

The keys that are not fields

A record also carries keys that address the object or steer the request, and those must not be mistaken for fields. They are named now, where only id was before:

CONTROL_FIELDS = ("id", "parent_path", "parent_uid", "path",
                  "portal_type", "transition", "uid")

That list is the set of keys the routes themselves read out of a record.

A note on what this changes for callers

A payload carrying a key that is not a field is refused where it used to be accepted. That is the point, and it is worth saying out loud: an integration that sends something extra and harmless will see a 400 it did not see before. The alternative is what we have today, which is that a typo in a field name is indistinguishable from success.

Verification

I confirm I have tested the PR thoroughly and coded it according to PEP8 standards.

@ramonski
ramonski force-pushed the fix/single-valued-dx-uidreference branch from 21ab0f5 to 759f4f6 Compare October 7, 2026 07:28
A name in a record that matched no field and no setter was dropped
with a line in the log, and the request answered that the object had
been created or updated. A caller asking for `Service` instead of
`services` was told that all was well and got back a profile with
nothing in it, which is how an afternoon goes missing.

It is refused now, and the message names the field the caller probably
meant:

    No field named 'Service' on AnalysisProfile. Did you mean 'services'?

The keys that address the object or steer the request rather than
naming a field (portal_type, parent_path, parent_uid, path, uid, id,
transition) are listed as such and skipped, as `id` already was.

This builds on #115. A name a Dexterity type kept from its Archetypes
days has to reach its field first; without that, every payload written
against the documented API, which uses those names throughout, would
now be refused.
@ramonski
ramonski force-pushed the fix/refuse-unknown-fields branch from 59dea71 to ab7a434 Compare October 7, 2026 07:29
@ramonski
ramonski requested a review from xispa October 8, 2026 06:02
@ramonski ramonski added the Enhancement ✨ Improvement to existing functionality label Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement ✨ Improvement to existing functionality

Development

Successfully merging this pull request may close these issues.

1 participant