Skip to content

Commit f2e3d7f

Browse files
committed
fix(service-datasource): federated validation skips the platform's unprovisioned injected anchors
A stored federated object is read with the anchors the platform injects (organization_id, created_by, updated_by, owner_id, owning_business_unit_id). Gate 2 compared them with the remote and reported each as missing_column at error severity, so a datasource with the default onMismatch 'fail' refused to boot. validateObjectUsing now skips the columns unprovisionedInjectedColumns names. Claude-Session: https://claude.ai/code/session_011K3zqE8Pv1Evw5hc8tZCnN Co-authored-by: Claude <noreply@anthropic.com>
1 parent 99b5420 commit f2e3d7f

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

‎packages/services/service-datasource/src/external-datasource-service.ts‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
suggestFieldTypeForSqlType,
3030
isCompatible,
3131
ExternalCatalogSchema,
32+
unprovisionedInjectedColumns,
3233
type ExternalCatalog,
3334
type SqlDialect,
3435
type FieldType,
@@ -661,8 +662,19 @@ export class ExternalDatasourceService implements IExternalDatasourceService {
661662
fieldToRemote.set(fieldName, remoteCol);
662663
}
663664

665+
// [#21788] The anchors the platform injects with NO storage behind them
666+
// (`organization_id`, the audit pair, `owner_id`,
667+
// `owning_business_unit_id` on a federated object) are not remote columns
668+
// and never were: the remote owns the schema. An object read as the
669+
// registry holds it — every stored object the metadata door or the import
670+
// saved, rehydrated at boot — carries them in `fields`, and comparing them
671+
// reported each as a `missing_column` error, which aborted the boot under
672+
// the default `onMismatch: 'fail'`. The spec's own provenance verdict
673+
// (#7865) names exactly those anchors; an author-declared field of the same
674+
// name is the author's and is still compared.
675+
const unprovisioned = new Set(unprovisionedInjectedColumns(obj));
664676
for (const [fieldName, field] of Object.entries(obj.fields ?? {})) {
665-
if (BUILTIN_COLUMNS.has(fieldName)) continue;
677+
if (BUILTIN_COLUMNS.has(fieldName) || unprovisioned.has(fieldName)) continue;
666678
const remoteCol = fieldToRemote.get(fieldName) ?? fieldName;
667679
if (ignore.has(remoteCol)) continue;
668680

0 commit comments

Comments
 (0)