@@ -20,7 +20,8 @@ import { OrchestrationError } from '@/lib/core/orchestration/types'
2020import { getEffectiveDecryptedEnv } from '@/lib/environment/utils'
2121import { principalUserId } from '@/lib/integrations/principal-scope.server'
2222import { toolExecutionOperations } from '@/lib/tool-execution/application/operations'
23- import { extractEnvVarName , isEnvVarReference } from '@/executor/constants'
23+ import { isEnvVarReference } from '@/executor/constants'
24+ import { resolveEnvVarReferences } from '@/executor/utils/reference-validation'
2425import { executeTool as executeRegistryTool } from '@/tools'
2526import type { ExecutableToolConfig } from '@/tools/types'
2627import { getTool } from '@/tools/utils'
@@ -82,18 +83,23 @@ function hostedKeyParamFor(
8283/**
8384 * Whether a `{{VAR}}` key resolves to a key of the caller's own.
8485 *
85- * The registry resolves the reference from this same environment before it
86- * decides on Sim's key, and a variable that is missing or empty leaves the
87- * parameter for Sim's key to fill.
86+ * Resolved exactly as the registry resolves it — same environment, same
87+ * options — before it decides on Sim's key. A variable that is missing or
88+ * empty leaves the parameter for Sim's key to fill.
8889 */
8990async function referencesOwnKey (
9091 value : unknown ,
9192 userId : string ,
9293 workspaceId : string
9394) : Promise < boolean > {
9495 if ( typeof value !== 'string' || ! isEnvVarReference ( value ) ) return false
95- const env = await getEffectiveDecryptedEnv ( userId , workspaceId )
96- return Boolean ( env [ extractEnvVarName ( value ) ] ?. trim ( ) )
96+ const missingKeys : string [ ] = [ ]
97+ const resolved = resolveEnvVarReferences (
98+ value ,
99+ await getEffectiveDecryptedEnv ( userId , workspaceId ) ,
100+ { allowEmbedded : false , missingKeys }
101+ )
102+ return missingKeys . length === 0 && typeof resolved === 'string' && resolved . trim ( ) . length > 0
97103}
98104
99105/**
0 commit comments