Skip to content

Commit 789bd93

Browse files
committed
fix: add loadDefault() for platform-scope preference on ambiguity
loadDefault() picks the platform/app/database-scoped instance when multiple module instances exist. This correctly resolves the functions-test scenario where both 'platform' and 'org' scoped invocation modules are provisioned — the worker should use the platform instance when no entity_type is provided.
1 parent a391203 commit 789bd93

8 files changed

Lines changed: 33 additions & 18 deletions

File tree

job/compute-worker/src/compute-log.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,11 @@ export class ComputeLogTracker {
4747
return;
4848
}
4949
if (err instanceof AmbiguousScopeError) {
50-
const all = await this.loader.computeLog.loadAll(this.databaseId);
51-
cfg = all[0];
50+
cfg = await this.loader.computeLog.loadDefault(this.databaseId);
5251
} else {
5352
throw err;
5453
}
5554
}
56-
if (!cfg) return;
5755

5856
const qualifiedTable = `"${cfg.publicSchema}"."${cfg.computeLogTable}"`;
5957
try {
@@ -93,13 +91,11 @@ export class ComputeLogTracker {
9391
return 0;
9492
}
9593
if (err instanceof AmbiguousScopeError) {
96-
const all = await this.loader.computeLog.loadAll(this.databaseId);
97-
cfg = all[0];
94+
cfg = await this.loader.computeLog.loadDefault(this.databaseId);
9895
} else {
9996
throw err;
10097
}
10198
}
102-
if (!cfg) return 0;
10399

104100
try {
105101
const result = await this.pool.query(

job/compute-worker/src/discovery.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ export class FunctionDiscovery {
3939
return await this.loader.function.load(this.databaseId, null);
4040
} catch (err) {
4141
if (err instanceof AmbiguousScopeError) {
42-
const all = await this.loader.function.loadAll(this.databaseId);
43-
return all[0];
42+
return await this.loader.function.loadDefault(this.databaseId);
4443
}
4544
throw err;
4645
}

job/compute-worker/src/invocation.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ export class InvocationTracker {
4040
} catch (err) {
4141
if (err instanceof ModuleNotProvisionedError) return null;
4242
if (err instanceof AmbiguousScopeError) {
43-
const all = await this.loader.invocation.loadAll(dbId);
44-
return all[0] ?? null;
43+
return await this.loader.invocation.loadDefault(dbId);
4544
}
4645
throw err;
4746
}

job/worker/src/compute-meter.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ export function logComputeUsage(pool: Pool, entry: MeterEntry): string {
5252
return await loader.invocation.load(databaseId, entry.scope ?? null);
5353
} catch (err) {
5454
if (err instanceof AmbiguousScopeError) {
55-
const all = await loader.invocation.loadAll(databaseId);
56-
return all[0];
55+
return await loader.invocation.loadDefault(databaseId);
5756
}
5857
throw err;
5958
}

job/worker/src/graph-complete.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ async function resolveGraph(pool: Pool, databaseId: string, scope?: string | nul
2727
return await getLoader(pool).graph.load(databaseId, scope ?? null);
2828
} catch (err) {
2929
if (err instanceof AmbiguousScopeError) {
30-
const all = await getLoader(pool).graph.loadAll(databaseId);
31-
return all[0];
30+
return await getLoader(pool).graph.loadDefault(databaseId);
3231
}
3332
throw err;
3433
}

job/worker/src/storage-meter.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ async function resolveComputeLog(pool: Pool, databaseId: string, scope: string |
3636
return await getLoader(pool).computeLog.load(databaseId, scope);
3737
} catch (err) {
3838
if (err instanceof AmbiguousScopeError) {
39-
const all = await getLoader(pool).computeLog.loadAll(databaseId);
40-
return all[0];
39+
return await getLoader(pool).computeLog.loadDefault(databaseId);
4140
}
4241
throw err;
4342
}

packages/agentic-server/src/inference-meter.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ async function resolveComputeLog(pool: Pool, databaseId: string, scope: string |
4646
return await getLoader(pool).computeLog.load(databaseId, scope);
4747
} catch (err) {
4848
if (err instanceof AmbiguousScopeError) {
49-
const all = await getLoader(pool).computeLog.loadAll(databaseId);
50-
return all[0];
49+
return await getLoader(pool).computeLog.loadDefault(databaseId);
5150
}
5251
throw err;
5352
}

packages/module-loader/src/generic-loader.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,31 @@ export class ModuleConfigLoader<T extends ScopedModuleConfig> {
103103
return all[0];
104104
}
105105

106+
/**
107+
* Platform-level scope preferences (app/platform/database are equivalent).
108+
* Used by loadDefault() to pick a non-entity instance when ambiguous.
109+
*/
110+
private static readonly PLATFORM_SCOPES = ['platform', 'app', 'database'];
111+
112+
/**
113+
* Load the default (platform-level) module instance.
114+
*
115+
* When only one instance exists, returns it. When multiple exist,
116+
* prefers platform/app/database scope over entity scopes (org, etc.).
117+
* Throws ModuleNotProvisionedError only if no instances exist at all.
118+
*/
119+
async loadDefault(databaseId: string): Promise<T> {
120+
const all = await this.loadAll(databaseId);
121+
if (all.length === 0) {
122+
throw new ModuleNotProvisionedError(this.moduleName, databaseId);
123+
}
124+
if (all.length === 1) return all[0];
125+
const platformMatch = all.find((c) =>
126+
ModuleConfigLoader.PLATFORM_SCOPES.includes(c.scope)
127+
);
128+
return platformMatch ?? all[0];
129+
}
130+
106131
/**
107132
* Invalidate cache for a specific database or all databases.
108133
*/

0 commit comments

Comments
 (0)