can1357/oh-my-pi · error · ToolError

JavaScript backend is disabled (PI_JS=0 or eval.js = false).

Error message

JavaScript backend is disabled (PI_JS=0 or eval.js = false).

What it means

This is the catch-all branch of resolveBackend: JavaScript is the default eval language, and if the JS backend is not allowed (eval.js setting false or PI_JS=0) the resolver refuses. Unlike py/rb/jl, JS has no availability probe here — the Node/Bun runtime is assumed present — so the only way to get this error is explicit disabling via config or env flag.

Source

Thrown at packages/coding-agent/src/tools/eval.ts:296

		return { backend: rubyBackend };
	}
	if (language === "julia") {
		if (!allowJl) throw new ToolError("Julia backend is disabled (PI_JL=0 or eval.jl = false).");
		const available = await juliaBackend.isAvailable(session, probeOpts);
		throwIfAborted(probeOpts?.signal);
		if (!available) {
			const alternatives = [allowJs ? '"js"' : null, allowPy ? '"py"' : null, allowRb ? '"rb"' : null].filter(
				Boolean,
			);
			throw new ToolError(
				alternatives.length > 0
					? `Julia backend is unavailable in this session. Pass language: ${alternatives.join(" or ")} or install Julia.`
					: 'Julia backend is unavailable in this session. Install Julia to use language: "jl".',
			);
		}
		return { backend: juliaBackend };
	}
	if (!allowJs) throw new ToolError("JavaScript backend is disabled (PI_JS=0 or eval.js = false).");
	return { backend: jsBackend };
}
function formatEvalInputLanguage(value: string): string {
	if (value === "py" || value === "python") return "python";
	if (value === "js" || value === "javascript") return "javascript";
	if (value === "rb" || value === "ruby") return "ruby";
	if (value === "jl" || value === "julia") return "julia";
	return value;
}

export class EvalTool implements AgentTool<typeof evalSchema> {
	readonly name = "eval";
	readonly approval = "exec" as const;
	readonly formatApprovalDetails = (args: unknown): string[] => {
		const params = args as Partial<EvalToolParams>;
		const language =
			typeof params.language === "string" ? formatEvalInputLanguage(params.language) : "javascript (default)";
		const code = typeof params.code === "string" ? params.code : "";

View on GitHub (pinned to 9690622007)

Solutions

  1. Set eval.js to true in settings (or remove the eval.js=false override) to re-enable the default JS backend.
  2. Remove PI_JS=0 from the environment or set PI_JS=1.
  3. Pass an explicitly enabled language ("py", "rb", or "jl") instead of relying on the JS default.

Example fix

// before
{ "code": "1+1" } // defaults to js, which is disabled
// after
{ "language": "py", "code": "1+1" }
// or re-enable JS: export PI_JS=1
Defensive patterns

Strategy: validation

Validate before calling

const backends = resolveEvalBackends(session);
const lang = backends.js ? "js" : backends.python ? "py" : null;
if (!lang) throw new Error("no eval backend enabled");
// call eval with explicit language instead of relying on the js default

Type guard

function jsEnabled(b: { js: boolean }): b is { js: true } { return b.js; }

Try / catch

try {
  await evalTool.execute(id, params, signal);
} catch (e) {
  if (e instanceof ToolError && e.message.includes("JavaScript backend is disabled")) {
    // retry with an explicitly enabled language or surface config guidance
  } else throw e;
}

Prevention

When it happens

Trigger: Calling eval with no language or language "js"/"javascript" when resolveEvalBackends reports js: false, i.e. the PI_JS environment flag is set to 0 or the eval.js setting is false.

Common situations: Hardened/locked-down configurations that disable JS eval for safety; users who set PI_JS=0 expecting only to restrict one language but calling eval without an explicit language; migrated configs where eval.js was turned off.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/80b9c0193d937ef8. Report an issue: GitHub.