kiota-typescript icon indicating copy to clipboard operation
kiota-typescript copied to clipboard

couldn't find navigation property then data

Open tracker1 opened this issue 7 months ago • 2 comments

Looks like the apiClientProxifier blows up when an instance is returned from an async function. I am loading some server-side configuration options before generating the client and wanted to return the client instance in a single pass.

export async function getApiClient() : Promise<ApiClient> {
  const ibOptions = await fetch('/api/auth/client-config').then(r => r.json());
  const credential = new InteractiveBrowserCredential(ibOptions);  
  const authProvider = new AzureIdentityAuthenticationProvider(credential, ['api://<api-client-id>/scopename']);
  const adapter = new FetchRequestAdapter(authProvider);
  adapter.baseUrl = location.origin;
  
  var client = createApiClient(adapter);
  return client;
}

When I call this method, I receive the error message couldn't find navigation property then data.

It looks like what is needed, is inside apiClientProxifier is a special name check for then that simply returns undefined in order to satisfy the Promise resolution logic.

tracker1 avatar May 07 '25 19:05 tracker1

You're right, I think a change before/after this block should suffice:

https://github.com/microsoft/kiota-typescript/blob/483ebdf8e7bef4059032d6124aedc80cb821ada9/packages/abstractions/src/apiClientProxifier.ts#L121-L126

Please feel free to open a PR for this. The team is undergoing a transition and prioritization of issues is a little challenging. Thank you.

musale avatar May 08 '25 12:05 musale

Bug is still present... will try to get a PR in this weekend.

tracker1 avatar Jun 20 '25 15:06 tracker1

Hi, any updates?

ofekR123 avatar Aug 07 '25 11:08 ofekR123

I just got bit by this today, I cannot use a generated Graph PIM client as a result.

JustinGrote avatar Aug 26 '25 21:08 JustinGrote

@JustinGrote as a workaround, you can wrap it in an object or array...

    // from inside async function
    return { client }; // or [client]

    // from calling function
    var {client} = await getMyClientInstance(...);

tracker1 avatar Oct 01 '25 19:10 tracker1

@JustinGrote as a workaround, you can wrap it in an object or array...

// from inside async function return { client }; // or [client]

Interesting workaround... Why does this help tho?

ofekR123 avatar Oct 01 '25 19:10 ofekR123

@ofekR123 because the wrapper object doesn't have a .then property and isn't a proxy... the issue is that the client is using a JS proxy, and throws when you try to access a property that doesn't exist... The Promise/Thenable interface when returning in an async function, will look for a .then property(function), subscribe to it and wait for that to finish before returning the calling function, because the proxy is configured to throw on an unknown property, .then it breaks when trying to return the Proxy(client) from an async function.

My PR simply defines this property handler and returns undefined which resolves the issue internally... wrapping the result effectively handles it without issue.. it's just clumsy and should be corrected in the project.

For me, my issue is that I'm not familiar with the test harness or orchestration in the project and hadn't had time to figure out how to create a negative and positive test for this issue.

tracker1 avatar Oct 01 '25 19:10 tracker1

@ofekR123 because the wrapper object doesn't have a .then property and isn't a proxy... the issue is that the client is using a JS proxy, and throws when you try to access a property that doesn't exist... The Promise/Thenable interface when returning in an async function, will look for a .then property(function), subscribe to it and wait for that to finish before returning the calling function, because the proxy is configured to throw on an unknown property, .then it breaks when trying to return the Proxy(client) from an async function.

My PR simply defines this property handler and returns undefined which resolves the issue internally... wrapping the result effectively handles it without issue.. it's just clumsy and should be corrected in the project.

For me, my issue is that I'm not familiar with the test harness or orchestration in the project and hadn't had time to figure out how to create a negative and positive test for this issue.

So in my function where I call the createClient function, I simply need to return { client} instead?

ofekR123 avatar Oct 01 '25 20:10 ofekR123