parcel-bundler/parcel · error · Error

Asset has an AST but no generate method is available on the

Error message

Asset has an AST but no generate method is available on the transform

What it means

When a transformer produces an AST, Parcel later needs to turn that AST back into source code via the transformer's `generate()`. The code path checks `transformer.generate && asset.ast` first; if the asset holds an AST but the transformer has no `generate`, Parcel cannot serialize the AST and rejects it as a contract violation.

Source

Thrown at packages/core/core/src/Transformation.js:692

      });
    let results = await normalizeAssets(this.options, transfomerResult);

    // Create generate and postProcess function that can be called later
    asset.generate = (): Promise<GenerateOutput> => {
      let publicAsset = new Asset(asset);
      if (transformer.generate && asset.ast) {
        let generated = transformer.generate({
          asset: publicAsset,
          ast: asset.ast,
          options: pipeline.pluginOptions,
          logger,
          tracer,
        });
        asset.clearAST();
        return Promise.resolve(generated);
      }

      throw new Error(
        'Asset has an AST but no generate method is available on the transform',
      );
    };

    let postProcess = transformer.postProcess;
    if (postProcess) {
      pipeline.postProcess = async (
        assets: Array<UncommittedAsset>,
      ): Promise<Array<UncommittedAsset> | null> => {
        let results = await postProcess.call(transformer, {
          assets: assets.map(asset => new MutableAsset(asset)),
          config,
          options: pipeline.pluginOptions,
          resolve,
          logger,
          tracer,
        });

View on GitHub (pinned to 59484858a1)

Solutions

  1. Implement `generate({asset, ast, options, logger})` on the transformer, returning `{content, map}`.
  2. If you don't need an AST, don't set `ast` on the asset — return code directly.
  3. Reuse an existing AST-capable transformer (e.g. `@parcel/transformer-js`) instead of a code-only one.

Example fix

// before
export default new Transformer({
  async transform({asset}) {
    asset.ast = parse(await asset.getCode());
    return [asset];
  }
});

// after
export default new Transformer({
  async transform({asset}) {
    asset.ast = parse(await asset.getCode());
    return [asset];
  },
  async generate({asset, ast, options}) {
    return {content: generate(ast), map: undefined};
  }
});
Defensive patterns

Strategy: type-guard

Validate before calling

// Only set ast when the transformer can generate from it.
if (typeof transformer.generate === 'function') {
  asset.ast = parsed;
}

Type guard

function canGenerate(t: {generate?: Function}): boolean {
  return typeof t.generate === 'function';
}

Prevention

When it happens

Trigger: A transformer returns/sets `ast` on the asset but does not implement a `generate({asset, ast, options})` method.

Common situations: Writing a custom transformer that parses to an AST for analysis but forgets the code-generation step.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/d27b383e83a0ab3f. Report an issue: GitHub.