JuliusBrussee/caveman · error

caveman build: source module syntax is not lexable in ${JSON

Error message

caveman build: source module syntax is not lexable in ${JSON.stringify(path)}

What it means

esmSourceSpecifiers() runs es-module-lexer's parse() over a source file and throws this error when parsing itself fails, wrapping the lexer error as cause. If the file cannot be lexed as an ES module, its import graph cannot be extracted, so the source closure is not computable and the build aborts with the file path in the message.

Source

Thrown at packages/agent/src/source-graph.ts:276

  return undefined;
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return value !== null && typeof value === "object" && !Array.isArray(value);
}

function isPathWithin(root: string, candidate: string): boolean {
  const child = relative(root, candidate);
  return child === "" || (!isAbsolute(child) && child !== ".." &&
    !child.startsWith("../") && !child.startsWith("..\\"));
}

function esmSourceSpecifiers(source: string, path: string): string[] {
  let imports: ReturnType<typeof parse>[0];
  try {
    [imports] = parse(source, path);
  } catch (error) {
    throw new Error(
      `caveman build: source module syntax is not lexable in ${JSON.stringify(path)}`,
      { cause: error },
    );
  }
  const specifiers: string[] = [];
  for (const item of imports) {
    if (item.d === -2) continue; // import.meta is metadata, not a dependency.
    if (item.n === undefined) {
      throw new Error(`caveman build: computed source dependency is not lockable in ${JSON.stringify(path)}`);
    }
    specifiers.push(item.n);
  }
  return specifiers;
}

function typescriptSourceSyntax(
  source: string,
  path: string,

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Open the path from the error message and fix the syntax error; the cause error carries the lexer's line/column.
  2. Run your normal lint/tsc pass before building so broken files fail there first.
  3. If the syntax is valid-but-new, pin a newer framework/lexer version that supports it.

Example fix

// before: src/broken.js
export const = bad syntax;

// after
export const value = "fixed";
Defensive patterns

Strategy: try-catch

Validate before calling

import { parse } from "es-module-lexer";
function isLexable(source: string, path: string): boolean {
  try { parse(source, path); return true; } catch { return false; }
}

Try / catch

try {
  await buildSourceGraph(root);
} catch (error) {
  if (error instanceof Error && error.message.includes("source module syntax is not lexable")) {
    // file path is in the message; error.cause carries the lexer error with line/column
  } else throw error;
}

Prevention

When it happens

Trigger: A .js/.mjs file with a genuine syntax error, or syntax the lexer version cannot handle (e.g. very new ECMAScript proposals or malformed code) anywhere in the reachable project graph.

Common situations: Building while the working tree has a half-edited file; a tool or codegen step emitting invalid JS; an es-module-lexer version lagging behind bleeding-edge syntax used in sources.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/d6d431a63b2aa9fc. Report an issue: GitHub.