{"record":{"id":"ca4441f44d01b178","repo":"anomalyco/sst","slug":"sst-aws-linkable-is-deprecated-use-sst-linkable-w","errorCode":null,"errorMessage":"sst.aws.linkable is deprecated. Use sst.Linkable.wrap instead.\nsst.Linkable.wrap(MyResource, (resource) => ({\n  properties: { ... },\n  with: [\n    sst.aws.permission({ actions: [\"foo:*\"], resources: [resource.arn] })\n  ]\n}))","messagePattern":"sst\\.aws\\.linkable is deprecated\\. Use sst\\.Linkable\\.wrap instead\\.\nsst\\.Linkable\\.wrap\\(MyResource, \\(resource\\) => \\((.+?),\n  with: \\[\n    sst\\.aws\\.permission\\((.+?)\\)\n  \\]\n\\}\\)\\)","errorType":"exception","errorClass":"VisibleError","httpStatus":null,"severity":"warning","filePath":"platform/src/components/aws/linkable.ts","lineNumber":21,"sourceCode":"\nexport const URL_UNAVAILABLE = \"http://url-unavailable-in-dev.mode\";\n\n/** @deprecated\n * instead try\n * ```\n * sst.Linkable.wrap(MyResource, (resource) => ({\n *   properties: { ... },\n *   with: [\n *     sst.aws.permission({ actions: [\"foo:*\"], resources: [resource.arn] })\n *   ]\n * }))\n * ```\n */\nexport function linkable<T>(\n  obj: { new (...args: any[]): T },\n  cb: (resource: T) => FunctionPermissionArgs[],\n) {\n  throw new VisibleError(\n    [\n      \"sst.aws.linkable is deprecated. Use sst.Linkable.wrap instead.\",\n      \"sst.Linkable.wrap(MyResource, (resource) => ({\",\n      \"  properties: { ... },\",\n      \"  with: [\",\n      '    sst.aws.permission({ actions: [\"foo:*\"], resources: [resource.arn] })',\n      \"  ]\",\n      \"}))\",\n    ].join(\"\\n\"),\n  );\n}\n","sourceCodeStart":3,"sourceCodeEnd":33,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/linkable.ts#L3-L33","documentation":"sst.aws.linkable() was the old way to register a custom resource class as linkable in SST. It has been removed and now unconditionally throws a VisibleError directing you to the replacement API, sst.Linkable.wrap, which supports richer properties and permission attachments.","triggerScenarios":"Calling sst.aws.linkable(MyResource, (resource) => [...]) inside a component definition or a .linkable() registration file, typically after upgrading SST from v2 to v3+ where the API was replaced.","commonSituations":"Upgrading an SST v2 project to v3 and keeping the old linkable.ts registration file; copying a legacy custom-resource example from old docs or blog posts.","solutions":["Replace sst.aws.linkable with sst.Linkable.wrap, passing the resource class and a callback returning { properties, with }","Convert the returned FunctionPermissionArgs array into the `with: [sst.aws.permission({ actions, resources })]` shape","Remove any imports of sst.aws.linkable and re-run the deploy"],"exampleFix":"// before\nsst.aws.linkable(MyResource, (resource) => [\n  { actions: [\"foo:*\"], resources: [resource.arn] }\n]);\n// after\nsst.Linkable.wrap(MyResource, (resource) => ({\n  properties: { arn: resource.arn },\n  with: [\n    sst.aws.permission({ actions: [\"foo:*\"], resources: [resource.arn] })\n  ]\n}));","handlingStrategy":"validation","validationCode":"// Guard before registering linkability\nif (\"linkable\" in sst.aws) {\n  throw new Error(\"sst.aws.linkable is removed; use sst.Linkable.wrap\");\n}","typeGuard":"function usesLegacyLinkable(api: unknown): api is { linkable: Function } {\n  return typeof api === \"object\" && api !== null && \"linkable\" in api;\n}","tryCatchPattern":"try {\n  registerLinkable();\n} catch (e) {\n  if (String(e).includes(\"Linkable.wrap\")) {\n    console.error(\"Migrate registration to sst.Linkable.wrap\");\n  }\n  throw e;\n}","preventionTips":["Search the codebase for `sst.aws.linkable` when upgrading SST versions","Follow the SST v3 migration guide for custom resource linking","Use sst.Linkable.wrap for all new custom resources","Pin and review the SST changelog before major upgrades"],"tags":["deprecation","linking","aws","api-migration"],"backgroundTag":"deprecated-api-migration","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}