oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73k stars 2.66k forks source link

ReferenceError: Cannot access uninitialized variable #2927

Open zfedoran opened 1 year ago

zfedoran commented 1 year ago

What version of Bun is running?

0.6.1

What platform is your computer?

Darwin 21.6.0 arm64 arm

What steps can reproduce the bug?

git clone https://github.com/bufbuild/connect-es-integration.git
cd connect-es-integration
cd express
npm install
bun run server.ts

What is the expected behavior?

The server should start and output the following.

Example by running npm start (without bun)

> buf-express@0.1.0 start
> tsx server.ts

The app is running on http://localhost:3000
Run `npm run client` for a terminal client.
Run `npm run serve` for a web client using CORS.

What do you see instead?

bun run server.ts

10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 | import { headerProtocolVersion } from "./headers.js";
15 | import { ConnectError } from "../connect-error.js";
   ^
ReferenceError: Cannot access uninitialized variable.
      at /Users/.../connect-es-integration/express/node_modules/@bufbuild/connect/dist/esm/protocol-connect/version.js:15:0
      at /Users/.../connect-es-integration/express/node_modules/@bufbuild/connect/dist/esm/protocol-connect/request-header.js:16:0
      at /Users/.../connect-es-integration/express/node_modules/@bufbuild/connect/dist/esm/protocol-connect/index.js:15:0
      at /Users/.../connect-es-integration/express/node_modules/@bufbuild/connect/dist/esm/connect-error.js:16:0
      at /Users/.../connect-es-integration/express/node_modules/@bufbuild/connect/dist/esm/index.js:14:0

Additional information

No response

Jarred-Sumner commented 1 year ago

sad i thought we fixed these

in the meantime, can you try bun build --target=bun ./server.ts

zfedoran commented 1 year ago

@Jarred-Sumner Thanks for the fast response. That does seem to help but this leads to another bug (perhaps related to https://github.com/oven-sh/bun/issues/1511 https://github.com/oven-sh/bun/issues/1811).

The bundle contains these lines:

...
var gzip2 = promisify(zlib.gzip);
var gunzip2 = promisify(zlib.gunzip);
var brotliCompress2 = promisify(zlib.brotliCompress); // <<<<< error (line 30795)
var brotliDecompress2 = promisify(zlib.brotliDecompress);
var compressionGzip = {
  name: "gzip",
  compress(bytes) {
    return gzip2(bytes, {});
  },
  decompress(bytes, readMaxBytes) {
    return wrapZLibErrors(gunzip2(bytes, {
      maxOutputLength: readMaxBytes
    }), readMaxBytes);
  }
};
var compressionBrotli = {
  name: "br",
  compress(bytes) {
    return brotliCompress2(bytes, {});
  },
  decompress(bytes, readMaxBytes) {
    return wrapZLibErrors(brotliDecompress2(bytes, {
      maxOutputLength: readMaxBytes
    }), readMaxBytes);
  }
};

Which throws the following:

469 |   return Object.prototype.hasOwnProperty.call(obj, prop);
470 | }
471 | var kCustomPromisifiedSymbol = Symbol.for("util.promisify.custom");
472 | var promisify = (exports.promisify = function promisify(original) {
473 | 
474 |   if (typeof original !== "function") throw new TypeError('The "original" argument must be of type Function');
                                               ^
TypeError: The "original" argument must be of type Function
      at promisify (node:util:474:44)
      at /Users/.../connect-es-integration/express/build.ts:30795:22

edit: Swapping those brotli functions with empty functions gets the server running but of course without brotliCompress/Decompress so its technically broken still.

Thinkscape commented 9 months ago

This is bizarre. Happens to me on 1.0.14. I've run madge to find circular deps and there are none ...

Tried bun run --target=bun file.ts but it didn't improve it.

robertherber commented 8 months ago

I'm also running into this. Some findings:

I'm guessing this might be related to something changing in the WebKit fork or when upgrading Safari on the Mac(?). How are the dependencies resolved here @Jarred-Sumner? I think it would be best if WebKit is bundled (or at least deterministically resolved) together with the bun version. Frustrating to have working code one day and the next it's broken, with seemingly the same environment (exactly same code and bun version).

Update: Suddenly the error has disappeared for me. I'm fairly sure it didn't work on my first attempt with 1.0.20, but now it does, and it also works with 1.0.19 which I'm 100% sure didn't work before. I also note that the latest Webkit release was last week - so probably not related after all? What could possibly cause this kind of lack of determinism?

Another possibility: Could it possibly be related to some kind of caching behaviour on the TypeScript config side? My computer might have restarted between it working, not working and working again 🤔

basemkhirat commented 8 months ago

Same for me: bun v1.0.20

     at processTicksAndRejections (:61:77)
16 |    @PrimaryGeneratedColumn("uuid")
17 |    id: string;
18 | 
19 |    @ManyToOne(() => Role, (role) => role.translations)
20 |    @JoinColumn({ name: "role_id" })
21 |    role: Role;
      ^
ReferenceError: Cannot access uninitialized variable.
      at /Users/basem/www/express-typescript/app/database/entities/role_translation.entity.ts:21:2
      at processTicksAndRejections (:61:77)
VigilioYonatan commented 7 months ago

--target=bun

Same for me: bun v1.0.20

     at processTicksAndRejections (:61:77)
16 |    @PrimaryGeneratedColumn("uuid")
17 |    id: string;
18 | 
19 |    @ManyToOne(() => Role, (role) => role.translations)
20 |    @JoinColumn({ name: "role_id" })
21 |    role: Role;
      ^
ReferenceError: Cannot access uninitialized variable.
      at /Users/basem/www/express-typescript/app/database/entities/role_translation.entity.ts:21:2
      at processTicksAndRejections (:61:77)

any update?

robertherber commented 7 months ago

Somehow we've gotten past this. Not quite sure what changed though, a restart of my laptop was involved I believe.

VigilioYonatan commented 7 months ago

Same for me: bun v1.0.20

     at processTicksAndRejections (:61:77)
16 |    @PrimaryGeneratedColumn("uuid")
17 |    id: string;
18 | 
19 |    @ManyToOne(() => Role, (role) => role.translations)
20 |    @JoinColumn({ name: "role_id" })
21 |    role: Role;
      ^
ReferenceError: Cannot access uninitialized variable.
      at /Users/basem/www/express-typescript/app/database/entities/role_translation.entity.ts:21:2
      at processTicksAndRejections (:61:77)

i hope that will fix soon. But i am using unknown as type

 @ManyToOne(() => Role, (role) => role.translations)
   @JoinColumn({ name: "role_id" })
   role: unknown;
blksnk commented 7 months ago

Got a similar issue running a test suite using bun test in our CI (GitHub actions). The same test suite runs fine locally.

Bun version for both CI and local environments: 1.0.25 Local environment: Darwin 21.6.0 arm64 arm (MacOs 14.0 Sonoma) Ci environment: ubuntu-latest (GitHub Actions)

Aside from the ReferenceError encountered and thus failing tests, the only difference between local and CI runs we were able to notice is the order the various tests are ran.

Local test runs seem to respect import dependency patterns (test files with dependencies run after their imports), whereas CI test runs do not seem to respect that pattern.

robertherber commented 7 months ago

Wow, just found the root issue. We had a run-away @ts-expect-error ignoring a variable that didn't exist. The really weird part here is that it sometimes passed - sometimes not.

Kotov584 commented 6 months ago

Still not fixed? I have this issue with TypeORM. This error appears from nowhere.

chadacious commented 6 months ago

I've been hitting this as well trying to port a larger project from nodejs to bun. Along with frequently hitting the nebulous segmentation fault errors as well (although re-arranging code in seemingly random ways seems to resolve these).

But in regard to Cannot access uninitialized variable, if you look at the build file from something like bun build --target=bun src/index.ts --outdir=dist, in my case using type-graphql and typegoose decorators at least, I see that indeed it is referencing classes before they are declared (is this due to a sort of circular reference issue).

203531 | __legacyDecorateClassTS([
203532 |   Field({ nullable: true }),
203533 |   typegoose7.prop({ _id: false }),
203534 |   __legacyMetadataTS("design:type", typeof IAPVerification === "undefined" ? Object : IAPVerification)
           ^
ReferenceError: Cannot access uninitialized variable.
      at /home/chad/projects/enjoy/apis/tsdb-api/dist/index.js:203534:3

Then somewhere below this code you will see class IAPVerification {} finally declared.

Is there some way to control this aspect of the bundler? Perhaps force it to make another sweep to reorder some of the bundled code to ensure the classes are declared before being referenced?

chadacious commented 6 months ago

FYI - I used madge to look for any circular dependencies in my typegoose models and correcting those resolved the problem for me.

UmutKDev commented 5 months ago

same error for me

ersinakinci commented 5 months ago

I keep getting this when using decorators in MikroORM, like so:

@Entity()
export default class Category extends BaseEntity {
  @ManyToOne(() => CategoryGroup, { deleteRule: "cascade" })
  categoryGroup!: CategoryGroup;  // ReferenceError: Cannot access uninitialized variable.
}

My workaround is to use a type alias in the annotation:

type CategoryGroupEntity = CategoryGroup;

@Entity()
export default class Category extends BaseEntity {
  @ManyToOne(() => CategoryGroup, { deleteRule: "cascade" })
  categoryGroup!: CategoryGroupEntity;  // works fine
}
cristianvnica commented 4 months ago

I'm getting this when using a for loop in Bun version 1.1.4

147 | for (let i = 0; i < reports.length; i++) { ^ ReferenceError: Cannot access uninitialized variable.

Borderliner commented 3 months ago

@ersinakinci Only this solution worked for me.

Leni-Vienne commented 2 months ago

Wow, i'm stuck hard on this. I was once able to make it go away by placing my imports after the export default router, but not this time. No typescript or class involved from my end

import express from 'express';
import { pool } from '../utils/db.js';

let router = express.Router();
router.get('/my_route', route1);
export default router;

async function route1(req, res) {
    try {
        console.log(req.query.id) // 25
        const id_element = req.query.id // ReferenceError: Cannot access uninitialized variable.

EDIT : the issue was caused by something like this, below the error pointed by bun, it was bad programming but bun couldn't point to the right place. so it's more of a logging/reporting issue. It's quite reproducible.

let a = 4
let b = 12
let c = 13

[a, b, c] = await Promise.all([Promise.resolve(a), Promise.resolve(b), Promise.resolve(c)])
console.log(a, b, c);
Jarred-Sumner commented 2 months ago

This will likely be fixed by https://github.com/WebKit/WebKit/pull/24122. Our synchronous import in Bun (require) is very similar to top-level await

benthayer commented 1 month ago

To get around this, we chose to just run our code from a docker container. The problem does not exist inside the docker container. Make sure to expose the correct port. Ours is 3000. The docker:build command builds the container and the docker command will run a shell from the docker container with the working directory mounted as the working directory in the container. Any changes made in the filesystem will be shared across your computer and the docker container since the directory is mounted in the docker container. bun-cli is the name of the container. package.json

{
  "scripts": {
    "docker": "docker run -it --rm -v $(pwd):/usr/src/app -w /usr/src/app bun-cli",
    "docker:build": "docker build -t bun-cli ."
  }
}

Dockerfile

# Use an official Node.js runtime as a base image
FROM node:16

# Install curl
RUN apt-get update && apt-get install -y curl

# Install bun
RUN curl -fsSL https://bun.sh/install | bash

# Set the bun directory in PATH
ENV PATH="/root/.bun/bin:$PATH"

# Set the working directory
WORKDIR /usr/src/app

# Expose the port the app runs on
EXPOSE 3000

# Define the default command
CMD ["sh"]