Excessive Stack Depth Comparing Types

by ADMIN 38 views

Bug Description

When attempting to extend Prisma to automatically apply a where clause to all queries, a developer encountered an excessive stack depth error. This issue arises when trying to query multiple temporal objects with a currentVersion property, requiring a way to override the default behavior.

Goal

The objective is to create a Prisma extension that automatically adds a currentVersion: true where clause to all queries by default, while allowing for the option to query all versions when needed.

Solution

The proposed solution involves extending Prisma to add new methods that would let the developer query all versions if needed. This would be achieved by creating a custom findManyAllVersions method that would override the default behavior.

Extension

The extension code is provided below:

new PrismaClient({
  log: ['query'],
}).$extends({
  model: {
    employeeBenefit: {
      async findManyAllVersions(args?: Prisma.EmployeeBenefitFindManyArgs) {
        const normalizedArgs = {
          ...(args || {}),
        } as Prisma.EmployeeBenefitFindManyArgs & {
          allVersions?: boolean;
        };

        normalizedArgs.allVersions = true;

        const context = Prisma.getExtensionContext(this);
        return context.findMany(normalizedArgs);
      },
      foo() {
        return this;
      },
    },
  },
  query: {
    employeeBenefit: {
      async findMany({ args, query }) {
        const normalizedArgs = {
          ...(args || {}),
        } as Prisma.EmployeeBenefitFindManyArgs & {
          allVersions?: boolean;
        };

        // Filter by currentVersion unless allVersions is true
        if (normalizedArgs.allVersions !== true) {
          normalizedArgs.where = {
            AND: [
              normalizedArgs.where || {},
              {
                currentVersion: true,
              },
            ],
          };
        }

        // Remove our custom property
        if ('allVersions' in normalizedArgs) {
          delete normalizedArgs.allVersions;
        }

        return query(normalizedArgs);
      },
    },
  },
});

Error

However, this extension results in an excessive stack depth error:

src/lib/prisma.ts:23:18 - error TS2321: Excessive stack depth comparing types 'EmployeeBenefitSelect<DefaultArgs>' and 'EmployeeBenefitSelect<InternalArgs & DefaultArgs>'.

23           return context.findMany(normalizedArgs);
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 1 error in src/lib/prisma.ts:23

Severity

This issue is considered major, as it breaks core functionality and prevents migrations from working.

Reproduction

A GitHub repository has been created to reproduce the issue: https://github.com/dmaksimov/prisma-max-depth

Expected vs. Actual Behavior

The expected behavior is for the inferred types to work fine, but the actual behavior is a maximum depth exceeded error.

Frequency

This issue is consistently reproducible.

Does this occur in development or production?

This issue occurs in both development and production environments.

Is this a regression?

No, this is not a regression.

Workaround

No workarounds have been found yet.

###isma Schema & Queries

The Prisma schema and queries are included above.

Prisma Config

// Add your `prisma.config.ts`

Logs & Debug Info

// Debug logs here

Environment & Setup

  • OS: macOS
  • Database: PostgreSQL
  • Node.js version: v20.11.0

Prisma Version

// Prisma version output
prisma                  : 6.7.0
@prisma/client          : 6.7.0
Computed binaryTarget   : darwin-arm64
Operating System        : darwin
Architecture            : arm64
Node.js                 : v20.11.0
TypeScript              : 5.8.3
Query Engine (Node-API) : libquery-engine 3cff47a7f5d65c3ea74883f1d736e41d68ce91ed (at node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Schema Engine           : schema-engine-cli 3cff47a7f5d65c3ea74883f1d736e41d68ce91ed (at node_modules/@prisma/engines/schema-engine-darwin-arm64)
Schema Wasm             : @prisma/prisma-schema-wasm 6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed
Default Engines Hash    : 3cff47a7f5d65c3ea74883f1d736e41d68ce91ed
Studio                  : 0.511.0

Conclusion

The excessive stack depth error encountered when extending Prisma to automatically apply a where clause to all queries is a complex issue. The proposed solution involves creating a custom findManyAllVersions method that would override the default behavior. However, this results in an excessive stack depth error. Further investigation is required to resolve this issue and provide a working solution.

Possible Solutions

  1. Re-evaluate the extension approach: Consider alternative approaches to extending Prisma, such as creating a repository for the model with proxy methods for findMany and findManyAllVersions.
  2. Optimize the extension code: Review the extension code to identify potential performance bottlenecks and optimize it to reduce the stack depth.
  3. Use a different data structure: Consider using a different data structure, such as a graph database, that can handle complex queries more efficiently.

Future Work

  • Investigate alternative approaches to extending Prisma.
  • Optimize the extension code to reduce the stack depth.
  • Consider using a different data structure to handle complex queries.

References

Acknowledgments

Q: What is the excessive stack depth error in Prisma?

A: The excessive stack depth error in Prisma occurs when the type checker is unable to resolve the types of the arguments being passed to a function, resulting in an infinite recursion and a stack overflow.

Q: What is the cause of the excessive stack depth error in Prisma?

A: The cause of the excessive stack depth error in Prisma is due to the way the type checker is handling the types of the arguments being passed to the findMany method. Specifically, it is unable to resolve the types of the args and query objects, leading to an infinite recursion.

Q: How can I reproduce the excessive stack depth error in Prisma?

A: To reproduce the excessive stack depth error in Prisma, you can create a Prisma schema with multiple models and then try to extend Prisma to add a custom findMany method that takes an args object as an argument. This will cause the type checker to become stuck in an infinite recursion, resulting in a stack overflow.

Q: What are some possible solutions to the excessive stack depth error in Prisma?

A: Some possible solutions to the excessive stack depth error in Prisma include:

  • Re-evaluating the extension approach: Consider alternative approaches to extending Prisma, such as creating a repository for the model with proxy methods for findMany and findManyAllVersions.
  • Optimizing the extension code: Review the extension code to identify potential performance bottlenecks and optimize it to reduce the stack depth.
  • Using a different data structure: Consider using a different data structure, such as a graph database, that can handle complex queries more efficiently.

Q: How can I optimize the extension code to reduce the stack depth?

A: To optimize the extension code to reduce the stack depth, you can try the following:

  • Use a more efficient data structure: Consider using a more efficient data structure, such as a graph database, that can handle complex queries more efficiently.
  • Reduce the number of recursive calls: Try to reduce the number of recursive calls in the extension code to minimize the stack depth.
  • Use a different approach: Consider using a different approach to extending Prisma, such as creating a repository for the model with proxy methods for findMany and findManyAllVersions.

Q: What are some best practices for avoiding the excessive stack depth error in Prisma?

A: Some best practices for avoiding the excessive stack depth error in Prisma include:

  • Use a more efficient data structure: Consider using a more efficient data structure, such as a graph database, that can handle complex queries more efficiently.
  • Reduce the number of recursive calls: Try to reduce the number of recursive calls in the extension code to minimize the stack depth.
  • Use a different approach: Consider using a different approach to extending Prisma, such as creating a repository for the model with proxy methods for findMany and findManyAllVersions.

Q: How can I get help with the excessive stack depth error in Prisma?

A: If you are experiencing issues with the excessive stack depth error in Prisma, you can try the following:

  • Check the Prisma documentation: The Prisma documentation provides a wealth of information on how to use Prisma and troubleshoot common issues.
  • Search online forums: Online forums, such as the Prisma GitHub repository and Stack Overflow, can be a great resource for finding answers to common questions and troubleshooting issues.
  • Reach out to the Prisma community: The Prisma community is active and helpful, and can often provide valuable insights and advice on how to troubleshoot issues.

Q: What are some common mistakes to avoid when extending Prisma?

A: Some common mistakes to avoid when extending Prisma include:

  • Not properly handling recursive calls: Failing to properly handle recursive calls can lead to an excessive stack depth error.
  • Not using a more efficient data structure: Using a less efficient data structure can lead to performance issues and an excessive stack depth error.
  • Not following best practices: Failing to follow best practices, such as reducing the number of recursive calls and using a more efficient data structure, can lead to performance issues and an excessive stack depth error.

Q: How can I ensure that my Prisma extension is properly optimized?

A: To ensure that your Prisma extension is properly optimized, you can try the following:

  • Use a profiling tool: Profiling tools, such as the Chrome DevTools, can help you identify performance bottlenecks and optimize your extension.
  • Use a code analysis tool: Code analysis tools, such as ESLint, can help you identify potential issues and optimize your extension.
  • Test your extension thoroughly: Thoroughly testing your extension can help you identify potential issues and optimize it for performance.