Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working sandbox app fails to deploy due to syntax errors (TS2345, TS2339), using Amplify demo code. #1458

Closed
AmplifyAnon opened this issue May 7, 2024 · 4 comments
Labels
pending-triage Incoming issues that need categorization

Comments

@AmplifyAnon
Copy link

Environment information

System:
  OS: Linux 6.1 Amazon Linux 2023
  CPU: (2) x64 Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz
  Memory: 5.94 GB / 7.55 GB
  Shell: /bin/bash
Binaries:
  Node: 20.12.2 - ~/.nvm/versions/node/v20.12.2/bin/node
  Yarn: undefined - undefined
  npm: 10.6.0 - ~/.nvm/versions/node/v20.12.2/bin/npm
  pnpm: undefined - undefined
NPM Packages:
  @aws-amplify/backend: 0.15.0
  @aws-amplify/backend-cli: 0.15.0
  aws-amplify: 6.2.0
  aws-cdk: 2.139.1
  aws-cdk-lib: 2.139.1
  typescript: 5.4.5

> lpm-react-amplify-gen2@0.0.0 npx
> cdk doctor --no-notices --  --no-color

AWS environment variables:
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables

Description

I made an initial Amplify app by following the official Amplify Gen 2 walkthrough. I got it to work in the sandbox. It then fails to deploy.

To recreate the error:

  1. Use a freshly created Cloud9 environment combined with a newly bootstrapped Amplify app and a new CodeCommit repository - everything clean.
  2. Follow these instructions - https://docs.amplify.aws/gen2/start/quickstart/vite-react-app/
  3. Work through all the bugs in the tutorial (beyond the scope of this question - ports need to be changed/opened, the original code references incorrect filenames, etc) and get the system to work locally in a sandbox.
  4. Get the whole thing loaded into a Git repository (in this case, CodeCommit) and link the Amplify app to the repository.
  5. Run the deployment (manually or automatic upon a Git push, if everything is working). Deployment fails.

Default options and settings and versions are used in all cases, unless specifically mentioned in the linked walkthrough.

This is the resulting syntax error:

 170 2024-05-01T22:08:22.641Z [INFO]: src/components/TodoList.tsx(14,14): error TS2345: Argument of type '{ readonly id: string; readonly createdAt: string; readonly updatedAt: string; content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; owner?: string | undefined; }[]' is not assignable to parameter of type 'SetStateAction<{ type: { readonly id: string; readonly createdAt: string; readonly updatedAt: string; } & { content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; } & { ...; }; }[]>'.
 171 Type '{ readonly id: string; readonly createdAt: string; readonly updatedAt: string; content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; owner?: string | undefined; }[]' is not assignable to type '{ type: { readonly id: string; readonly createdAt: string; readonly updatedAt: string; } & { content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; } & { ...; }; }[]'.
 172 Property 'type' is missing in type '{ readonly id: string; readonly createdAt: string; readonly updatedAt: string; content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; owner?: string | undefined; }' but required in type '{ type: { readonly id: string; readonly createdAt: string; readonly updatedAt: string; } & { content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; } & { ...; }; }'.
 173 2024-05-01T22:08:22.645Z [INFO]: src/components/TodoList.tsx(20,13): error TS2345: Argument of type '{ readonly id: string; readonly createdAt: string; readonly updatedAt: string; content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; owner?: string | undefined; }[]' is not assignable to parameter of type 'SetStateAction<{ type: { readonly id: string; readonly createdAt: string; readonly updatedAt: string; } & { content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; } & { ...; }; }[]>'.
 174 Type '{ readonly id: string; readonly createdAt: string; readonly updatedAt: string; content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; owner?: string | undefined; }[]' is not assignable to type '{ type: { readonly id: string; readonly createdAt: string; readonly updatedAt: string; } & { content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; } & { ...; }; }[]'.
 175 Type '{ readonly id: string; readonly createdAt: string; readonly updatedAt: string; content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; owner?: string | undefined; }' is not assignable to type '{ type: { readonly id: string; readonly createdAt: string; readonly updatedAt: string; } & { content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; } & { ...; }; }'.
 176 src/components/TodoList.tsx(42,25): error TS2339: Property 'id' does not exist on type '{ type: { readonly id: string; readonly createdAt: string; readonly updatedAt: string; } & { content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; } & { ...; }; }'.
 177 src/components/TodoList.tsx(42,35): error TS2339: Property 'content' does not exist on type '{ type: { readonly id: string; readonly createdAt: string; readonly updatedAt: string; } & { content?: Nullable<string> | undefined; done?: Nullable<boolean> | undefined; priority?: "low" | ... 3 more ... | undefined; } & { ...; }; }'.
 178 2024-05-01T22:08:22.710Z [ERROR]: !!! Build failed
 179 2024-05-01T22:08:22.711Z [ERROR]: !!! Error: Command failed with exit code 2

TodoList.tsx is a direct copy and paste from the tutorial:

import { useState, useEffect } from "react";
import { generateClient } from "aws-amplify/data";
import type { Schema } from "../../amplify/data/resource";

export default function TodoList() {
  // generate your data client using the Schema from your backend
  const client = generateClient<Schema>();

  const [todos, setTodos] = useState<Schema["Todo"][]>([]);

  async function listTodos() {
    // fetch all todos
    const { data } = await client.models.Todo.list();
    setTodos(data);
  }

  useEffect(() => {
  listTodos()
  const sub = client.models.Todo.observeQuery().subscribe(({ items }) =>
   setTodos([...items])
  );

  return () => sub.unsubscribe();
}, []);

  return (
    <div>
      <h1>Todos</h1>
      <button onClick={async () => {
        // create a new Todo with the following attributes
        const { errors, data: newTodo } = await client.models.Todo.create({
          // prompt the user to enter the title
          content: window.prompt("title"),
          done: false,
          priority: 'medium'
        })
        console.log(errors, newTodo);
      }}>Create</button>

      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>{todo.content}</li>
        ))}
      </ul>
    </div>
  );
}

../../amplify/data/resource is directly from AWS and looks like this:

import { type ClientSchema, a, defineData } from '@aws-amplify/backend';

/*== STEP 1 ===============================================================
The section below creates a Todo database table with a "content" field. Try
adding a new "isDone" field as a boolean. The authorization rule below
specifies that any user authenticated via an API key can "create", "read",
"update", and "delete" any "Todo" records.
=========================================================================*/

const schema = a.schema({
  Todo: a
    .model({
      content: a.string(),
    })
    .authorization((allow) => [allow.guest()]),
});

export type Schema = ClientSchema<typeof schema>;
export const data = defineData({
  schema,
  authorizationModes: {
    defaultAuthorizationMode: 'iam',
  },
});

/*== STEP 2 ===============================================================
Go to your frontend source code. From your client-side code, generate a
Data client to make CRUDL requests to your table. (THIS SNIPPET WILL ONLY
WORK IN THE FRONTEND CODE FILE.)
Using JavaScript or Next.js React Server Components, Middleware, Server 
Actions or Pages Router? Review how to generate Data clients for those use
cases: https://docs.amplify.aws/gen2/build-a-backend/data/connect-to-API/

=========================================================================*/

/*
"use client"
import { generateClient } from "aws-amplify/data";
import type { Schema } from "@/amplify/data/resource";
const client = generateClient<Schema>() // use this Data client for CRUDL requests
*/

/*== STEP 3 ===============================================================
Fetch records from the database and use them in your frontend component.
(THIS SNIPPET WILL ONLY WORK IN THE FRONTEND CODE FILE.)
=========================================================================*/

/* For example, in a React component, you can use this snippet in your
  function's RETURN statement */

// const { data: todos } = await client.models.Todo.list()
// return <ul>{todos.map(todo => <li key={todo.id}>{todo.content}</li>)}</ul>

For completeness, here is package.json (autogenerated and untouched):

{
  "name": "lpm-react-amplify-gen2",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "aws-amplify": "^6.2.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@aws-amplify/backend": "^0.15.0",
    "@aws-amplify/backend-cli": "^0.15.0",
    "@types/react": "^18.2.66",
    "@types/react-dom": "^18.2.22",
    "@typescript-eslint/eslint-plugin": "^7.2.0",
    "@typescript-eslint/parser": "^7.2.0",
    "@vitejs/plugin-react": "^4.2.1",
    "aws-cdk": "^2.139.1",
    "aws-cdk-lib": "^2.139.1",
    "constructs": "^10.3.0",
    "esbuild": "^0.20.2",
    "eslint": "^8.57.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.6",
    "tsx": "^4.7.3",
    "typescript": "^5.4.5",
    "vite": "^5.2.0"
  }
}

Since this all works in the sandbox, it seems like there must be some version difference between all the stuff installed for the sandbox compared to what gets deployed and used to build.

One problem I solved (as part of step 2, above) was the failure of npx amplify sandbox, it was segfaulting and core dumping. This is apparently due to an issue with Node 20.12, so you must fall back to 20.11. I thought that might be the source of the issue, so I added some commands to do that fallback in the amplify.yml (Amplify app->Hosting->build options), with no success. I did not try doing the same thing by specifying a custom build container, as that seems redundant and unnecessary if the amplify.yml approach didn't help. It was using the 20.11 version in the deployment during that test, according to the console printout.

For what it's worth, the Cloud9 IDE is littered with warnings, mostly they seem to be similar type errors. An alleged fix for this is to change the Typescript version setting in the IDE to match the command-line/sandbox enviroment, but there doesn't seem to be such a setting (most people only talk about using VSCode, not Cloud9). Regardless of these warnings (errors?) being left unresolved, the Amplify sandbox eventually worked as intended.

I am not sure if I need to be focusing on syntax/type problems in the code provided by the tutorial (there were other problems that had to be solved in it to get the sandboxed version to work) or if it's something in the configuration of the deployment or something else entirely. Obviously the two environments do not match, so this is likely to crop up again in other code, if not resolved at the environment configuration level.

@AmplifyAnon AmplifyAnon added the pending-triage Incoming issues that need categorization label May 7, 2024
@Zhuohui-Li
Copy link

Zhuohui-Li commented May 8, 2024

Upgrade your @aws-amplify/backend and @aws-amplify/backend-cli packages to latest and then use useState<Schema["Todo"]["type"][]>([])
See TypeScript type helpers for Amplify Data

@ykethan
Copy link
Contributor

ykethan commented May 8, 2024

@AmplifyAnon thank you for reaching out. As @Zhuohui-Li suggested do upgrade to the latest version of the packages. The vite starter template had also been updated with the latest packages to use the schema type helpers.

@ykethan ykethan added the pending-response Issue is pending response from author label May 8, 2024
@AmplifyAnon AmplifyAnon reopened this May 9, 2024
@github-actions github-actions bot removed the pending-response Issue is pending response from author label May 9, 2024
@AmplifyAnon
Copy link
Author

This seems to have solved the issue, thanks.

I'd like to understand what happened here, might be helpful for reference.

  1. Why did the deployment environment not match the sandbox?
  2. Why did the AWS-provided demo code not work?
  3. What changed when I upgraded (@aws-amplify/backend-cli was already up to date, only @aws-amplify/backend got updated) my development environment and how did that change the deployment but not the sandbox?

Thanks again.

@ykethan
Copy link
Contributor

ykethan commented May 21, 2024

Hey, the @aws-amplify/backend contain the changes to the constructs which may have been out of date with the GA release version in your local clone. To verify if the project does use the latest packages, you can try re-installing the latest versions of @aws-amplify/backend and @aws-amplify/backend-cli.

Closing the issue, do reach out if you are experiencing issues with our latest versions of @aws-amplify/backend and @aws-amplify/backend-cli .

@ykethan ykethan closed this as not planned Won't fix, can't repro, duplicate, stale May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pending-triage Incoming issues that need categorization
Projects
None yet
Development

No branches or pull requests

3 participants