FirebaseExtended / FirebaseExtended/action-hosting-deploy

[BUG] Deployment fails with Unexpected token 'a' - firebase-tools output parsing is fragile

Open
#463 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
809
Forks
232
PR merge metrics
No merged PRs in 30d

Description

### Action config
```
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount: '${{ secrets.}}'
channelId: live
projectId:
target: production
env:
FIREBASE_CLI_EXPERIMENTS: webframeworks
```

### Error message
```
Deploying to production site
/usr/local/bin/npx firebase-tools@latest deploy --only hosting:production --project ... --json

added 1174 packages in 45s

189 packages are looking for funding
run `npm fund` for details
Error: Unexpected token 'a', "
added 1174"... is not valid JSON
***
conclusion: 'failure',
output: ***
title: 'Deploy preview failed',
summary: `Error: Unexpected token 'a', "\nadded 1174"... is not valid JSON`
***
***
```
### Expected behavior
```
Deploying to production site
/usr/local/bin/npx firebase-tools@latest deploy --only hosting:production --project ... --json
npm warn exec The following package was not found and will be installed: firebase-tools@15.22.1
npm warn deprecated node-domexception@1.0.0: Use your platform's native DOMException instead
npm warn deprecated json-ptr@3.1.1: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
npm warn deprecated uuid@9.0.1: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
npm warn deprecated glob@10.5.0: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
Failed to find esbuild with npx which: Error: Command failed: npx which esbuild
esbuild not found, installing...

added 2 packages, and audited 1578 packages in 6s

332 packages are looking for funding
run `npm fund` for details

54 vulnerabilities (2 low, 38 moderate, 11 high, 3 critical)

To address issues that do not require attention, run:
npm audit fix

To address all issues (including breaking changes), run:
npm audit fix --force

Run `npm audit` for details.
npm warn deprecated glob@8.1.0: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated google-p12-pem@4.0.1: Package is no longer maintained
npm warn deprecated uuid@8.3.2: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
npm warn deprecated uuid@9.0.1: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
npm warn deprecated uuid@9.0.1: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).

added 1174 packages in 45s

189 packages are looking for funding
run `npm fund` for details
***
"status": "success",
"result": ***
"hosting": "projects/.../sites/.../versions/..."
***
***::endgroup::
***
details_url: 'https://production.web.app/',
conclusion: 'success',
output: ***
title: 'Production deploy succeeded',
summary: '[production.web.app](https://production.web.app/)'
***
***
```
### Actual behavior

Builds that worked with 0.10 now broken with 0.11

### Investigation summary
Our firebase-tools JSON itself is valid and unchanged. The failure is in how the action captures and parses stdout.

#### Suspected root cause
`execWithCredentials` in `src/deploy.ts` returns only the last stdout chunk:
```
return deployOutputBuf.length
? deployOutputBuf[deployOutputBuf.length - 1].toString("utf-8")
: "";
```
deployProductionSite / deployPreview then JSON.parse() that single chunk. This assumes the `firebase-tools --json` blob is always the last thing written to stdout.

That presumably breaks under Node 24, which bundles npm 11 (Node 20 bundled npm 10). npm's install summary (added N packages in …) and funding notice (N packages are looking for funding) are written to stdout (via npm's output() / reifyOutput). Between npm 10 and npm 11 the flush ordering of that summary relative to the npm exec-spawned child changed:
- npm 10 (Node 20): npm's summary landed on stdout before the firebase JSON - last chunk was the JSON - parse succeeded.
- npm 11 (Node 24): the summary is flushed after the child's output - last chunk is `\nadded 1174 packages…` - JSON.parse fails.

Relying on chunks is fragile. Would suggest slicing `{` `}` symbols instead.

Contributor guide

Open the contributing guide

Research direction

Start in src/deploy.ts at execWithCredentials and trace how deployProductionSite and deployPreview consume its stdout. Reproduce the Node 24/npm 11 output ordering if possible, then verify that Firebase's JSON remains parseable when npm installation summaries follow it. Done means deployments no longer fail on trailing npm stdout while the reported deployment result is preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions, node.js, typescript
Domain
ci-cd, devops
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.