I’m getting a circular dependency error when I try...
# help
r
I’m getting a circular dependency error when I try to build my app but I don’t understand the error message:
Copy code
Error: 'some-stage-the-app-sst-coreFunctionsStack' depends on 'some-stage-the-app-sst-marketingStack' (some-stage-the-app-sst-coreFunctionsStack -> some-stage-the-app-sst-marketingStack/marketingBucket/Bucket/Resource.Arn). Adding this dependency (some-stage-the-app-sst-marketingStack -> some-stage-the-app-sst-coreFunctionsStack/resourcePhotoBucket/Bucket/Resource.Ref) would create a cyclic reference.
This implies to me that coreFunctionsStack imports, directly or indirectly, the marketingStack but it doesn’t. However, the opposite is true. Then the second half of the error that seems to say that importing the resourcePhotoBucket into coreFunctionsStack is the problem but that doesn’t happen either. resourcePhotoBucket is created in coreFunctionsStack and isn’t used at all by marketing Stack.
a
This is also how I would understand it. Weird if there is nothing in the stack code you are overlooking.
r
Working through it now but struggling to find anything but will report back
Ok, I’ve narrowed this down but I don’t understand why it causes a problem. In a stack I’m importing and using another stack.
Copy code
const { resourcePhotoBucket } = sst.use(coreResourcesStack);
In the importing stack I can use the resourcePhotoBucket resource in permissions blocks for functions but as soon as I try to add a function as a notification, it causes the error I pasted above. I.e. if I comment out the
resourcePhotoBucket.addNotifications
block in the following code, it works. Uncomment, it breaks
Copy code
const handleResizeUploadedPhoto = new sst.Function(ctx.stack, 'OmwResizeUploadedPhoto', {
    handler: 'src/main/handler/resourceConfig/resourcePhotoHandler.handleResizeUploadedPhoto',
    permissions: [primaryTable, resourcePhotoBucket],
    environment: omwEnvironment,
  });
  console.log('bundled omwCreatePhoto');
  resourcePhotoBucket.addNotifications(ctx.stack, {
    photoCreated: {
      type: 'function',
      function: handleResizeUploadedPhoto,
      events: ['object_created'],
    },
  });
a
What happens if you remove the resourcePhotoBucket permission of the handleResizeUploadedPhoto function?
r
Ok, further digging reveals that in the coreFunctions stack there’s a function that needs permission to access the resourcePhotoBucket. To get this working I’ve needed to invert the dependency, the stack that the code above lives in now imports the function ( via
use()
) and attaches the permissions to it. I haven’t tested if this works yet but it does build. The problem we have is related to a thread I was involved in the other day where we have various optional modules in our app. If those modules are purchased then some core modules need access to resources that the optional modules add to the application. For example, we have a stats module, if and only if the customer purchases the marketing module we need to allow stats to access marketing tables. This leads to a quite complex interdependent set of functional stacks. I think this is still simpler than the monolithic approach we were using before but quickly gets quite knotty. Unfortunately the error message wasn’t accurate in this case which meant chasing down a few dead ends before realising what the real problem was
a
I understood a few of these words 😀
anyway, it sounds like you figured it out?
f
Hey @Ross Coundon, I’m sure you are aware of this. But just to clarify, when you do:
Copy code
// marketingStack
const { resourcePhotoBucket } = use(coreFunctionStack);
Doing this alone doesn’t add any inter stack dependency. The dependency is ONLY added when the
resourcePhotoBucket
is being used. For example, when you do this:
Copy code
// marketingStack
const { resourcePhotoBucket } = use(coreFunctionStack);

new Function(stack, "fn", {
  ...
  permissions: [resourcePhotoBucket]
});
In this case,
resourcePhotoBucket's ARN
is being used. Behind the scene: •
coreFunctionStack
exports the bucket’s ARN; and •
marketingStack
imports it Hence the dependency is formed.
The error suggests: •
coreFunctionsStack
references `marketingStack's marketingBucket's ARN`; and •
marketingStack
references
coreFunctionStack's resourcePhotoBucket's ARN
Hence the cyclic reference.