Skip to content

[eas-cli] Fix invalid json for eas update with --json flag#3659

Merged
douglowder merged 2 commits intoexpo:mainfrom
Mookiies:fix/fingerprint-silent-json-output
Apr 30, 2026
Merged

[eas-cli] Fix invalid json for eas update with --json flag#3659
douglowder merged 2 commits intoexpo:mainfrom
Mookiies:fix/fingerprint-silent-json-output

Conversation

@Mookiies
Copy link
Copy Markdown
Contributor

@Mookiies Mookiies commented Apr 30, 2026

@expo/fingerprint spawns subprocesses concurrently (autolinking, react-native config, ExpoConfigLoader) that can write to stdout, corrupting the parent process's output when --json is in use. The silent option exists specifically to suppress this, but was never set. The function is already named WithoutLogging so this is the correct default regardless of --json.

Why

We get this output often when running eas update with --json and --emit-metadata. The actual json conflict changes and flakes across update runs.

Executing eas update --branch staging --message "message" --private-key-path ~/keys/private-key.pem --clear-cache --emit-metadata --json --non-interactive
...
- Computing project fingerprints
✖ Failed to compute project fingerprints
⏩ To skip this step, set the environment variable: EAS_SKIP_AUTO_FINGERPRINT=1
Expected ':' after property name in JSON at position 2048
    Error: update command failed.

Exited with code exit status 1
ℹ 25 iOS assets, 25 Android assets (maximum: 2000 total per update). Learn more about asset limits: https://expo.fyi/eas-update-asset-limits
- Computing project fingerprints
✖ Failed to compute project fingerprints
⏩ To skip this step, set the environment variable: EAS_SKIP_AUTO_FINGERPRINT=1
Unexpected token 'R', ..."       "D"Release",
"... is not valid JSON
    Error: update command failed.

Wha'ts going on

1. `--json` monkey-patches `process.stdout`

eas-cli/src/utils/json.ts#L11-L12 — when `--json` is passed, eas-cli redirects `process.stdout.write → process.stderr.write` so progress logs don't pollute the final JSON output.

2. `@expo/fingerprint` spawns 5–6 subprocesses concurrently

@expo/fingerprint/src/sourcer/Sourcer.ts#L44-L79 — fingerprinting runs `getExpoAutolinkingAndroid`, `getExpoAutolinkingIos`, `getCoreAutolinkingFromExpoAndroid`, `getCoreAutolinkingFromExpoIos`, `getCoreAutolinkingFromRncCli`, and `getExpoConfig` all via `Promise.all()`. Each spawns a separate OS process.

3. Subprocess stdout is not subject to the in-process redirect

These are separate OS processes — the `process.stdout.write` monkey-patch in the parent has no effect on them. Any stray `console.log` from those subprocesses gets captured and `JSON.parse()`d by the parent.

4. There is a known IPC fallback that writes directly to stdout

@expo/fingerprint/src/ExpoConfigLoader.ts#L43-L46 — if `process.send` (IPC) is unavailable, `ExpoConfigLoader` falls back to `console.log(result)`, writing a multi-KB JSON blob directly to stdout, which then contaminates the parent's JSON stream.

5. The fix exists in `@expo/fingerprint` but eas-cli never uses it

eas-cli/src/fingerprint/cli.ts#L89-L108 — `@expo/fingerprint` has a `silent: true` option specifically to suppress subprocess stdout pollution in JSON contexts, but `createFingerprintWithoutLoggingAsync` never sets it.

How

Suppress output from fingerprinting by suppressing output

Test Plan

Repeatedly run eas update --branch staging --message "message" --emit-metadata --json --non-interactive and watch for intermitent failures on fingerprinting fail due to invalid JSON. If it always works and doesn't flake good to go.

@Mookiies Mookiies marked this pull request as ready for review April 30, 2026 11:14
@github-actions
Copy link
Copy Markdown

Subscribed to pull request

File Patterns Mentions
**/* @douglowder

Generated by CodeMention

@Mookiies Mookiies changed the title [eas-cli] Fix invalid json when for eas update with --json [eas-cli] Fix invalid json for eas update with --json flag Apr 30, 2026
@douglowder
Copy link
Copy Markdown
Contributor

Looks good, please add a changelog entry in CHANGELOG.md

Mookiies and others added 2 commits April 30, 2026 10:28
…ithoutLoggingAsync

@expo/fingerprint spawns subprocesses concurrently (autolinking, react-native
config, ExpoConfigLoader) that can write to stdout, corrupting the parent
process's output when --json is in use. The silent option exists specifically
to suppress this, but was never set. The function is already named
WithoutLogging so this is the correct default regardless of --json.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Mookiies Mookiies force-pushed the fix/fingerprint-silent-json-output branch from 20ce5fe to 3b47edd Compare April 30, 2026 17:29
@Mookiies
Copy link
Copy Markdown
Contributor Author

@douglowder Rebased onto latest main to avoid conflicts in changelog and added new entry

@douglowder douglowder merged commit 3d691d6 into expo:main Apr 30, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants