denoland/deno · error

Cannot represent compiler option '{name}' as a generated JSX

Error message

Cannot represent compiler option '{name}' as a generated JSX pragma.

What it means

When publishing, Deno inlines JSX compiler options (`jsxImportSource`, `jsxImportSourceTypes`, `jsxFactory`, `jsxFragmentFactory`) into published files as `/** @jsx ... */` pragma comments. `is_safe_unquoted_comment_value` accepts only non-empty values with no `*/`, no whitespace, and no control characters; anything else cannot be written faithfully into a comment, so publish fails naming the offending option.

Source

Thrown at cli/tools/publish/module_content.rs:32

use deno_graph::ModuleGraph;
use deno_resolver::cache::LazyGraphSourceParser;
use deno_resolver::cache::ParsedSourceCache;
use deno_resolver::deno_json::CompilerOptionsResolver;
use deno_resolver::workspace::ResolutionKind;
use lazy_regex::Lazy;

use super::diagnostics::PublishDiagnostic;
use super::diagnostics::PublishDiagnosticsCollector;
use super::unfurl::PositionOrSourceRangeRef;
use super::unfurl::SpecifierUnfurler;
use super::unfurl::SpecifierUnfurlerDiagnostic;
use super::unfurl::SpecifierUnfurlerSys;
use crate::sys::CliSys;
use crate::tools::unfurl_utils::is_safe_unquoted_comment_value;

fn jsx_pragma(name: &str, value: &str) -> Result<String, AnyError> {
  if !is_safe_unquoted_comment_value(value) {
    return Err(deno_core::anyhow::anyhow!(
      "Cannot represent compiler option '{name}' as a generated JSX pragma."
    ));
  }
  Ok(format!("/** @{name} {value} */"))
}

struct JsxFolderOptions<'a> {
  jsx_runtime: &'static str,
  jsx_classic: Option<Cow<'a, deno_ast::JsxClassicOptions>>,
  jsx_import_source: Option<String>,
  jsx_import_source_types: Option<String>,
}

#[sys_traits::auto_impl]
pub trait ModuleContentProviderSys: SpecifierUnfurlerSys {}

pub struct ModuleContentProvider<TSys: ModuleContentProviderSys = CliSys> {
  specifier_unfurler: SpecifierUnfurler<TSys>,

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Set the JSX option to a plain identifier path with no whitespace, no comment terminators, and no control characters (letters, digits, dots, underscores, dollar signs)
  2. Remove the offending option entirely if nothing uses it
  3. Run `deno publish --dry-run` to confirm the pragma generation succeeds

Example fix

// before — deno.json
{
  "compilerOptions": {
    "jsxFactory": "h.createElement "
  }
}
// after
{
  "compilerOptions": {
    "jsxFactory": "h.createElement"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

# fail fast before publish: JSX option values must be non-empty,
# with no whitespace, no control chars, and no */
deno eval 'const c = JSON.parse(Deno.readTextFileSync("deno.json")).compilerOptions ?? {};
for (const k of ["jsxFactory", "jsxFragmentFactory", "jsxImportSource", "jsxImportSourceTypes"]) {
  const v = c[k];
  if (v === undefined) continue;
  if (v === "" || /\s/.test(v) || /[\u0000-\u001f]/.test(v) || v.includes("*/")) {
    console.error(`unsafe ${k}: ${JSON.stringify(v)}`); Deno.exit(1);
  }
}'

Type guard

// value can be embedded safely as an unquoted /** @jsx <value> */ pragma
const isSafePragmaValue = (v: string): boolean =>
  v.length > 0 && !v.includes("*/") && !/\s|[\u0000-\u001f\u007f]/.test(v);

Prevention

When it happens

Trigger: A deno.json `compilerOptions` JSX value containing a space, newline, `*/`, or a control character — e.g. `"jsxFactory": "h.createElement "` with a trailing space — while publishing files that use JSX.

Common situations: Copy-pasted compiler options with stray whitespace; template-generated deno.json inserting newlines into values; deliberately exotic factory strings such as `my lib.h`.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/6ec532ec77b32995. Report an issue: GitHub.