Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Query errors get a read-only `stack` on Node 22+

Open Beginner friendly
#1,227 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 7 days

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
javascript, nodejs, postgresql
Domain
backend, database

Research direction

Start in src/connection.js at queryError, where Object.defineProperties replaces the error's stack. Reproduce the issue with Node 22+ using the provided strict-mode example, then verify the query-error path preserves writable and configurable stack attributes. Done means assigning a new stack no longer throws for errors produced by a query.

Written by the indexing model from the issue text.

Description

queryError in src/connection.js (3.4.9; the same code is on master) appends the query origin like this:

Object.defineProperties(err, {
  stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
  // ...
})

Since Node 22, stack on an Error instance is an own accessor property. Redefining it with only value turns it into a data property, and writable defaults to false. As a result every query error ends up with a read-only stack. Strict-mode code that rewrites the stack then throws, and error-normalizing frameworks do rewrite it.

Repro (Node 22.23, 24.0, 24.21)
'use strict'
const e = new Error('x')
Object.defineProperties(e, { stack: { value: e.stack } })
e.stack = 'y' // TypeError: Cannot assign to read only property 'stack' of object 'Error: x'

With postgres.js:

'use strict'
const err = await sql`select 1/0`.catch(e => e)
err.stack = 'y' // same TypeError
Suggested fix
stack: { value: /* ... */, enumerable: options.debug, writable: true, configurable: true },

This restores the attributes the property had before Node 22.

Impact

The Vercel Workflow step executor rewrites a thrown error's stack before it records a retry. That assignment threw inside its catch block, so a transient database error left the step running until its lease expired, instead of retrying it.

Dominant language
JavaScript
Stars
8.7k
Forks
389
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from porsager/postgres

All issues in porsager/postgres

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.