Skip to content

spec(data): mapping lookup transform params (object / fromField / toField / autoCreate) are authorable and read by nothing #10329

Description

@os-elon

Found while writing the Data Modeling import-mappings page (epic #10206, card #10213). Filed unassigned for domain:spec triage; not fixed there, per that card's non-goals.

The shape

ImportFieldMappingSchema.params in packages/spec/src/data/mapping.zod.ts declares four keys whose only stated purpose is to steer the lookup transform:

  • object — "Lookup Object"
  • fromField — "Match on (e.g. name)"
  • toField — "Value to take (e.g. id)"
  • autoCreate — "Create if missing"

They also carry a full alias set (lookupObject/targetObject, match/matchOn/matchField/keyField, returnField/valueField, create/createIfMissing/upsert), so an author who reaches for any of eight other spellings is actively routed onto them.

Nothing reads them

The only consumer of a mapping artifact is the import path. In packages/rest/src/import-mapping.ts, applyMappingToRows handles lookup in the same branch as none:

case'none':
case'lookup': {// lookup values resolve downstream via metaMapmapped[first(entry.target)]=row[first(entry.source)];break;}

Reference resolution happens afterwards in import-coerce.ts, driven by the target object's own field metadata (buildFieldMetaMap), never by these keys. Grepping the repo for fromField and autoCreate outside mapping.zod.ts and its own tests returns only unrelated identifiers (sql-driver.tsuniqueIndexesFromFields, tenant.zod.tsautoCreateSchema/autoCreateDatabase).

The liveness ledger already records this, as a sub-walk boundary under fieldMapping rather than as a verdict of its own — packages/spec/liveness/mapping.json:

SUB-WALK BOUNDARY, recorded not hidden: params' lookup-specific keys (object/fromField/toField/autoCreate) are read by nothing — reference resolution comes from the target object's own field definitions, not from these — and they sit one level below the drill, so only this note governs them.

So the state is known and deliberately parked, not undiscovered. What it does not have is an ADR-0049 enforce-or-remove disposition.

Why it is worth a decision rather than a note

params is a strictObject, so it rejects a misspelling loudly — which makes these four the opposite case: they are accepted loudly. An author writing params: { object: 'account', fromField: 'name', autoCreate: true } gets a clean parse, a clean defineStack() build, and an import that silently ignores every one of them. autoCreate is the one with teeth: it reads as "create the referenced record when the name does not match", and what actually happens is that the row fails with an unresolved-reference error.

Options

  1. Remove the four keys under ADR-0049 (with the alias entries converted to guidance so the eight spellings land on a prescription rather than a "did you mean"). Matches how extractQuery / errorPolicy / batchSize left the same schema in 17.0.0.
  2. Implement them in applyMappingToRows — a per-entry lookup resolution that overrides the object-metadata default. This is a second reference-resolution dialect on the import path, which is what the existing comment declines to build.

Option 1 looks right from here, but it is domain:spec's call.

Impact on docs

content/docs/data-modeling/import-mappings.mdx (card #10213) documents the lookup transform as a pass-through and carries an explicit warning that these four params are not read, pointing at this issue. That warning should be deleted along with the keys if option 1 lands.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions