Skip to content

fix(cli): prevent double extension in temp file for stdin markdown with --ext#1399

Merged
antongolub merged 1 commit intogoogle:mainfrom
gin0606:main
Feb 7, 2026
Merged

fix(cli): prevent double extension in temp file for stdin markdown with --ext#1399
antongolub merged 1 commit intogoogle:mainfrom
gin0606:main

Conversation

@gin0606
Copy link
Contributor

@gin0606 gin0606 commented Feb 6, 2026

Fixes the issue where echo '...' | npx zx --ext='.md' produces a temp file named zx.md.md, causing Node.js to fail with ERR_UNKNOWN_FILE_EXTENSION.

After transformMarkdown() converts markdown to JavaScript, the temp file should use .mjs. However, getFilepath(dir, base) fell back to argv.ext (.md), resulting in a double extension. This fix explicitly passes EXT (.mjs) to prevent the fallback.

Before

$ printf '# Test\n\n```js\necho("hello from markdown")\n```\n' | npx zx --verbose --ext='.md'
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".md" for /Users/gin0606/zx.md.md
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:185:9)
    at defaultGetFormat (node:internal/modules/esm/get_format:211:36)
    at defaultLoadSync (node:internal/modules/esm/load:158:16)
    at #loadAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:795:12)
    at #loadSync (node:internal/modules/esm/loader:815:49)
    at ModuleLoader.load (node:internal/modules/esm/loader:780:26)
    at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:526:31)
    at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:571:36)
    at afterResolve (node:internal/modules/esm/loader:624:52)
    at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:630:12) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

After

$ printf '# Test\n\n```js\necho("hello from markdown")\n```\n' | node build/cli.js --verbose --ext='.md'
hello from markdown

…th --ext .md

Pass EXT (.mjs) explicitly when creating the temp file after markdown
transformation to avoid falling back to argv.ext, which caused the
temp file to be named zx.md.md instead of zx.md.mjs.
@google-cla
Copy link

google-cla bot commented Feb 6, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@antongolub
Copy link
Collaborator

antongolub commented Feb 6, 2026

@gin0606,

Let's try this: tempPath = tempPath || getFilepath(dir, base)

@gin0606
Copy link
Contributor Author

gin0606 commented Feb 6, 2026

Thank you for the suggestion, @antongolub!

I did consider using tempPath = tempPath || getFilepath(dir, base), but I think it may not fully address the issue in the .md case.

Here’s my understanding of the behavior when reading from stdin with --ext='.md':

  1. Line 212: tempPath is set to …/zx.md via getFilepath($.cwd, 'zx', argv.ext)
  2. Line 229: path.parse(tempPath) results in ext='.md' and base='zx.md'
  3. Line 233: The if (ext === '.md') branch runs transformMarkdown(), converting the markdown to JavaScript
  4. Line 235: The temporary file needs a .mjs extension so that Node.js can execute the transformed script

If we apply tempPath = tempPath || getFilepath(dir, base) at line 235, tempPath already has a value (…/zx.md), so that assignment would be skipped, leaving the extension as .md. In this scenario, Node.js would then fail with ERR_UNKNOWN_FILE_EXTENSION, since the file contains JavaScript but still has a .md extension.

That said, applying your suggestion at line 231 does make sense to me, as it would avoid an unnecessary reassignment when tempPath is already set. Would you be open to updating the PR to use tempPath = tempPath || getFilepath(dir, base) at line 231, while keeping the explicit EXT handling at line 235?

@antongolub antongolub merged commit 2f6896e into google:main Feb 7, 2026
30 checks passed
@gin0606
Copy link
Contributor Author

gin0606 commented Feb 7, 2026

@antongolub
Thanks for getting this merge 🙏
Looking forward to it being available in a future release.

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