amplify-backend
amplify-backend copied to clipboard
Amplify deploy fails when using function resolver with env by TypeScript error
Environment information
System:
OS: Windows 11 10.0.22631
CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
Memory: 4.69 GB / 15.79 GB
Binaries:
Node: 20.12.0 - ~\AppData\Local\Volta\tools\image\node\20.12.0\node.EXE
Yarn: undefined - undefined
npm: 10.5.0 - ~\AppData\Local\Volta\tools\image\npm\10.5.0\bin\npm.CMD
pnpm: undefined - undefined
NPM Packages:
@aws-amplify/backend: 0.13.2
@aws-amplify/backend-cli: 0.13.0
aws-amplify: 6.0.30
aws-cdk: Not Found
aws-cdk-lib: 2.138.0
typescript: 5.4.5
AWS environment variables:
AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
AWS_SDK_LOAD_CONFIG = 1
AWS_STS_REGIONAL_ENDPOINTS = regional
No CDK environment variables
Description
Code
Structure
amplify
├───data
│ └───resource.ts
└───functions
└───function-with-env
├───handler.ts
└───resource.ts
Implementations
- amplify/functions/function-with-env/handler.ts
// ...
// Ref. https://docs.amplify.aws/gen2/build-a-backend/functions/#accessing-environment-variables
/* @ts-noncheck directive for first 'amplify sandbox' run to avoid non-existence */
import { env } from '$amplify/env/function-with-env';
// ...
type FunctionWithEnvHandler = Schema['<query>']['functionHandler'];
export const handler: FunctionWithEnvHandler = async () => {
const apiHost = env['API_HOST'];
const apiKey = env['API_KEY'];
// ... list items from outside service and resolve types ...
return customTypeArray;
}
- amplify/functions/function-with-env/resource.ts
import { defineFunction, secret } from '@aws-amplify/backend';
const apiHost = process.env.API_HOST as string;
const apiKey = secret('API_KEY');
const environment = {
API_HOST: apiHost,
API_KEY: apiKey,
};
export const functionWithEnv= defineFunction({
environment,
timeoutSeconds: 10,
});
- amplify/data/resource.ts
import { functionWithEnv } from '../functions/function-with-env/resource';
// ...
const schemaopt = {
<custom-type>: a
.customType({
// typedef
}),
<query>: a
.query()
.returns(a.ref('<custom-type>').array())
.handler([a.handler.function(functionWithEnv)])
.authorization((auth) => [auth.guest(), auth.authenticated()]),
};
const schemaImpl = a.schema(schemaopt);
export type Schema = ClientSchema<typeof schemaImpl>;
export const data = defineData({
schema: schemaImpl,
authorizationModes: {
defaultAuthorizationMode: 'userPool',
},
});
// ...
Others
- .amplify/generated/env/function-with-env.ts (git ignored)
// This file is auto-generated by Amplify. Edits will be overwritten.
export const env = process.env as LambdaProvidedEnvVars & AmplifyBackendEnvVars;
/** Lambda runtime environment variables, see https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime */
type LambdaProvidedEnvVars = {
// ... auto generated settings ...
};
/** Amplify backend environment variables available at runtime, this includes environment variables defined in `defineFunction` and by cross resource mechanisms */
type AmplifyBackendEnvVars = {
API_HOST: string;
API_KEY: string;
};
- amplify/tsconfig.json
{
"compilerOptions": {
"target": "es2022",
"module": "es2022",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"paths": {
"$amplify/*": ["../.amplify/generated/*"]
}
}
}
Error detail
Sandbox deploy is succeeded. But deploy on Amplify CI/CD is failed.
Deploy log
2024-04-24T10:07:52.788Z [INFO]: # Executing command: npx amplify pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
2024-04-24T10:07:59.702Z [INFO]:
2024-04-24T10:08:05.537Z [INFO]: amplify/functions/<function-with-env>/handler.ts(4,21): error TS2307: Cannot find module '$amplify/env/<function-with-env>' or its corresponding type declarations.
2024-04-24T10:08:05.573Z [INFO]:
2024-04-24T10:08:05.573Z [WARNING]: amplify pipeline-deploy
Command to deploy backends in a custom CI/CD pipeline. This command is not intended to be used locally.
[...]
2024-04-24T10:08:05.574Z [INFO]: SyntaxError: TypeScript validation check failed.
Resolution: Fix the syntax and type errors in your backend definition.
Cause:
2024-04-24T10:08:05.634Z [ERROR]: !!! Build failed
2024-04-24T10:08:05.634Z [INFO]: Please read more about Amplify Hosting's support for SSR frameworks to find if your build failure is related to an unsupported feature: https://docs.aws.amazon.com/amplify/latest/userguide/amplify-ssr-framework-support.html. You may also find this troubleshooting guide useful: https://docs.aws.amazon.com/amplify/latest/userguide/troubleshooting-ssr-deployment.html
2024-04-24T10:08:05.634Z [ERROR]: !!! Error: Command failed with exit code 1
Expected
I want to meet these usecases.
- Success 'npx amplify sandbox' (generated env is existing)
- Success 'npx amplify sandbox' (generated env is not existing / first execution)
- Success Amplify CI/CD
What method should I take?(How to avoid TS check, wait for fix, or else ...)
Hey @mm-k-takashima, thank you for reaching out. I was able to reproduce the issue. Marking as bug for further investigation.
@mm-k-takashima on the local sandbox could you remove the .amplify/generated folder and restart the sandbox? this should regenerate the env files. Could you let us know if sandbox throws Cannot find module '$amplify/env/<function-with-env>' error.
@ykethan
I tried it.
- amplify/functions/function-with-env/handler.ts
// remove @ts-noncheck directive
import { env } from '$amplify/env/function-with-env';
### delete .amplify/generated/env and check it.
$ > npx tsc
$ > amplify/functions/<function-with-env>/handler.ts:4:21 - error TS2307: Cannot find module '$amplify/env/<function-with-env>' or its corresponding type declarations.
$ > 4 import { env } from '$amplify/env/<function-with-env>';
Found 1 error in amplify/functions/<function-with-env>/handler.ts:4
### restart sandbox
$ > aws sso login --profile project-x-profile
### sso login logs ... ###
$ > npx amplify sandbox --profile project-x-profile
### stack creation logs ... ###
$ > [Sandbox] Detected file changes while previous deployment was in progress. Invoking 'sandbox' again
File written: amplifyconfiguration.json
And I confirmed .amplify/generated/env/function-with-env.ts generation has been succeeded.
// This file is auto-generated by Amplify. Edits will be overwritten.
export const env = process.env as LambdaProvidedEnvVars & AmplifyBackendEnvVars;
/** Lambda runtime environment variables, see https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime */
type LambdaProvidedEnvVars = {
/** The handler location configured on the function. */
_HANDLER: string;
/** The X-Ray tracing header. This environment variable changes with each invocation. */
_X_AMZN_TRACE_ID: string;
/** The default AWS Region where the Lambda function is executed. */
AWS_DEFAULT_REGION: string;
/** The AWS Region where the Lambda function is executed. If defined, this value overrides the AWS_DEFAULT_REGION. */
AWS_REGION: string;
/** The runtime identifier, prefixed by AWS_Lambda_ (for example, AWS_Lambda_java8). */
AWS_EXECUTION_ENV: string;
/** The name of the function. */
AWS_LAMBDA_FUNCTION_NAME: string;
/** The amount of memory available to the function in MB. */
AWS_LAMBDA_FUNCTION_MEMORY_SIZE: string;
/** The version of the function being executed. */
AWS_LAMBDA_FUNCTION_VERSION: string;
/** The initialization type of the function, which is on-demand, provisioned-concurrency, or snap-start. */
AWS_LAMBDA_INITIALIZATION_TYPE: string;
/** The name of the Amazon CloudWatch Logs group for the function. */
AWS_LAMBDA_LOG_GROUP_NAME: string;
/** The name of the Amazon CloudWatch Logs stream for the function. */
AWS_LAMBDA_LOG_STREAM_NAME: string;
/** AWS access key. */
AWS_ACCESS_KEY: string;
/** AWS access key ID. */
AWS_ACCESS_KEY_ID: string;
/** AWS secret access key. */
AWS_SECRET_ACCESS_KEY: string;
/** AWS Session token. */
AWS_SESSION_TOKEN: string;
/** The host and port of the runtime API. */
AWS_LAMBDA_RUNTIME_API: string;
/** The path to your Lambda function code. */
LAMBDA_TASK_ROOT: string;
/** The path to runtime libraries. */
LAMBDA_RUNTIME_DIR: string;
/** The locale of the runtime. */
LANG: string;
/** The execution path. */
PATH: string;
/** The system library path. */
LD_LIBRARY_PATH: string;
/** The Node.js library path. */
NODE_PATH: string;
/** For X-Ray tracing, Lambda sets this to LOG_ERROR to avoid throwing runtime errors from the X-Ray SDK. */
AWS_XRAY_CONTEXT_MISSING: string;
/** For X-Ray tracing, the IP address and port of the X-Ray daemon. */
AWS_XRAY_DAEMON_ADDRESS: string;
/** The environment's time zone. */
TZ: string;
};
/** Amplify backend environment variables available at runtime, this includes environment variables defined in `defineFunction` and by cross resource mechanisms */
type AmplifyBackendEnvVars = {
API_HOST: string;
API_KEY: string;
};
But deploy fails because of TS2307 .
Hey @mm-k-takashima, apologies for the delay. Wasn't able to reproduce the issue.
Could you provide us your amplify.yml script present on the Amplify console -> build settings
It would be great if you provide us reproduction steps or a Github repository with minimal reproduction to dive deeper into the issue.
@ykethan Thank you for your reasearch.
My amplify.yml is below.
version: 1
backend:
phases:
build:
commands:
- echo "API_HOST=$API_HOST" >> amplify/.env # Tried to create an adapter class for backend environment variable.
- npm ci
- npx amplify pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- .next/cache/**/*
- node_modules/**/*
As an additional context, I am using Next.js. This may be affecting this. Below are the files that may be relevant.
- /tsconfig.json
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./app/*"],
"@@/*": ["./*"],
"$amplify/*": ["./.amplify/generated/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
- next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true
};
export default nextConfig;
- package.json
{
"name": "amplify-testing-geo",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "vitest --passWithNoTests",
"lint": "next lint",
"format": "prettier --write --ignore-path .gitignore './**/*.{js,jsx,ts,tsx,json,css}' && next lint --fix"
},
"volta": {
"node": "20.12.0",
"npm": "10.5.0"
},
"dependencies": {
"@aws-amplify/geo": "^3.0.27",
"@aws-amplify/ui-react": "^6.1.8",
"@aws-amplify/ui-react-geo": "^2.0.13",
"aws-amplify": "^6.0.28",
"dotenv": "^16.4.5",
"next": "14.1.4",
"prism-react-renderer": "^2.3.1",
"react": "^18.2.0",
"react-code-block": "^1.0.0",
"react-dom": "^18.2.0",
"react-icons": "^5.1.0"
},
"devDependencies": {
"@aws-amplify/backend": "^0.13.0",
"@aws-amplify/backend-cli": "^0.13.0",
"@testing-library/react": "^14.3.1",
"@types/node": "^20.12.7",
"@types/react": "^18.2.79",
"@types/react-dom": "^18.2.25",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@vitejs/plugin-react": "^4.2.1",
"aws-cdk-lib": "^2.138.0",
"constructs": "^10.3.0",
"esbuild": "^0.20.2",
"eslint": "^8.57.0",
"eslint-config-next": "14.1.4",
"eslint-config-prettier": "^9.1.0",
"jsdom": "^24.0.0",
"lefthook": "^1.6.10",
"prettier": "^3.2.5",
"tsx": "^4.7.2",
"typescript": "^5.4.5",
"vitest": "^1.5.0"
}
}
It would be great if you provide us reproduction steps or a Github repository with minimal reproduction to dive deeper into the issue.
Sorry, this cannot be done immediately. Could you please wait a week or so?
Hey sure, do add a reply on this thread. would be happy in diving into this.
I have Similar errors.
./amplify/data/deletePostHandler/handler.ts:4:21
Type error: Cannot find module '$amplify/env/CommunityBoardDeletePost' or its corresponding type declarations.
2 | import { Amplify } from "aws-amplify";
3 | import { generateClient } from "aws-amplify/data";
> 4 | import { env } from "$amplify/env/CommunityBoardDeletePost";
| ^
5 |
6 | const modelIntrospection = {
7 | version: 1,
tsconfig settings and env file generation have completed successfully. However, an error occurs when building next.js.
In addition to tsconfig.json in the amplify directory, the problem was resolved by setting the following settings as the paths of tsconfig.json directly under the next.js project.
$amplify/*": ["./.amplify/generated/*"]
But doing so will result in a new type error.
Conversion from type 'ProcessEnv' to type 'LambdaProvidedEnvVars & AmplifyBackendEnvVars' may be wrong as they cannot overlap sufficiently with each other. If you do this intentionally, convert the expression to 'unknown' first.
Type 'ProcessEnv' is missing the following properties from type 'LambdaProvidedEnvVars': _HANDLER, _X_AMZN_TRACE_ID, AWS_DEFAULT_REGION, AWS_REGION, 20, etc. ts(2352)
This can be resolved by manually setting unknown, but it takes time. Is there any solution?
@ykethan
I apologies for the delay of reply.
Since Amplify became GA, I was trying to see if the same problem occurs with the new version(@aws-amplify/backend: 1.0.0).
https://github.com/aws-amplify/amplify-backend/issues/1374#issuecomment-2090889848
As it turns out, the first problem shown Cannot find module '$amplify/env/<function-with-env>' no longer occurs.
I don't know what caused the problem.
But since the issue has been resolved, I think that this issue can be closed.
However, instead of the first problem being resolved, I now have a problem regarding ProcessEnv as indicated by @rnrnstar2 in the file: $amplify/generated/env/function-name.ts .
Type 'ProcessEnv' is missing the following properties from type 'LambdaProvidedEnvVars': _HANDLER, _X_AMZN_TRACE_ID, AWS_DEFAULT_REGION, AWS_REGION, 20, etc. ts(2352)
Should we create another assignment on this issue or should we continue in this thread?
Hey @rnrnstar2 @mm-k-takashima, did run a similar error recently on the frontend build with nextjs
2024-05-14T17:03:29.973Z [WARNING]: Failed to compile.
2024-05-14T17:03:29.977Z [WARNING]: ./amplify/function/handler.ts:1:21
Type error: Cannot find module '$amplify/env/say-hello' or its corresponding type declarations.
adding a exclude with "exclude": ["node_modules","amplify/**/*"] on the root tsconfig seems to have mitigated the error on the frontend build.
instead of the paths could you try setting the exclude and let us know if this mitigates the issue.
@ykethan
I added "exclude": ["node_modules", ".amplify", "./amplify"] to the root tsconfig, and resolved the problem.
A lot of thanks for your support!
@mm-k-takashima thank you for the confirmation. Marking this as documentation, to add this information to the troubleshooting document.
I'm running into the same issue with a Vue + Vite project, and neither adding the exclude nor adding to the path seemed to fix it. The only workaround I have is to add .amplify directory to include in tsconfig.app.json, but even then the shorthand $amplify won't work, even after adding it to path
(for clarification's sake, here's my tsconfig.app.json)
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "amplify/**/*", ".amplify/generated/**/*"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"$amplify/*": [
"../.amplify/generated/*"
]
}
}
}
Happy to give whatever other info can be helpful
Hey folks :wave: there are a few default tsconfig configurations that appear to be picking up the generated files from Amplify. We'll work towards documenting this soon, and maybe a message/codemod to help avoid this, but in the meantime you should be able to exclude the amplify and .amplify directories in your tsconfig
{
"exclude": ["amplify/**/*", ".amplify/**/*"]
}
Amplify will perform type-checking on sandbox and pipeline-deploy using the tsconfig local to the amplify backend (amplify/tsconfig.json). If you'd like to extend your base configuration you can add it to the localized tsconfig.
Alternatively, if you work within a monorepo you can move your backend to its own package and export the Schema and outputs for ease of sharing with your other apps. For example, in your backend package's package.json
{
"name": "my-backend",
"private": true,
"exports": {
"./schema": "./amplify/data/resource.ts",
"./outputs": "./amplify_outputs.json"
}
}
Just letting you all know, I had this exact problem, excluding the files solved it immediately. I suppose it's already on the works but changing the cli tool for the init to modify the tsconfig.json file to add those lines might be a very good Idea.
I'm thankful I found this. Good luck everyone.
I seem to still be having the issue even when excluding it.
It works with my sandbox but as soon as I push it to github and the build starts, I get this:
This is going to sound crazy and I don't know why it is but this only happened when I renamed a folder to an uppercase letter instead of a lowercase letter. I reverted my commit back and forth to see. That is literally the only difference. Is there maybe something that gets cached when this runs?
npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
Hi Team,
Just to let you know,
I'm facing the same issue by using the quickstart template for React on the Gen 2 Documentation.
-> Following this part of the documentation and trying to push to prod it still throws the following error "2024-06-05T05:34:30.549Z [INFO]: amplify/backend.ts(4,26): error TS2307: Cannot find module './functions/say-hello/resource' or its corresponding type declarations."
I've already to add the exclude line on the root config file and it still throws the same build error.
Attached my tsconfig root file
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"exclude": ["node_modules", ".amplify", "./amplify","amplify/**/*", ".amplify/**/*"],
"references": [{ "path": "./tsconfig.node.json" }]
}
If there have been any updates or maybe an advice it would be great!
Thank you :D
having the same issue here :/
Same issue for me... Exclusions don't seem to be working... Any news on this?
Hey @CBougoZ is your function named custom-authorizer? can you share the defineFunction definition?
Hi @josefaidt,
Please, tell me that I am missing something obvious...
@CBougoZ the generated env file name is based on the Function name, which if not specified falls back to the directory name. Can you specify name: "custom-authorizer"? With the current setup I believe the generated file name is $amplify/env/data (this gets generated to .amplify/generated/env/data.ts)
@josefaidt First of all thanks for your support. Yesterday it was getting late (I am located in Greece), so I had to go to bed. Unfortunately, what you suggested didn't do the trick. I moved the custom-authorizer.ts into a separate amplify/functions/custom-authorizer/handler.ts file. I also moved the defineFunction invocation from amplify/data/resoure.ts into amplify/functions/custom-authorizer/resource.ts file. So that basically meant that the defaults were used. Now it is working. I don't know why it wasn't working before. Thanks again!
No worries @CBougoZ! Glad to hear you're back up and running!
Closing the issue with the documentation merge https://github.com/aws-amplify/docs/pull/7681 https://docs.amplify.aws/react/build-a-backend/troubleshooting/cannot-find-module-amplify-env/
Add a exclude still not working for me :/
I am using the Amplify React Template