{"record":{"id":"43b8745fc747a352","repo":"google/zx","slug":"no-quote-function-is-defined-fail-docs-url-quo","errorCode":null,"errorMessage":"No quote function is defined: ${Fail.DOCS_URL}/quotes","messagePattern":"No quote function is defined: (.+?)/quotes","errorType":"exception","errorClass":"Fail","httpStatus":null,"severity":"critical","filePath":"src/core.ts","lineNumber":296,"sourceCode":"    if (snapshot) {\n      this._snapshot = snapshot\n      this._resolve = resolve!\n      this._reject = reject!\n      if (snapshot.halt) this._stage = 'halted'\n      try {\n        this.build()\n      } catch (err) {\n        this.finalize(ProcessOutput.fromError(err as Error), true)\n      }\n    } else ProcessPromise.disarm(this)\n  }\n  // prettier-ignore\n  private build(): void {\n    const $ = this._snapshot\n    if (!$.shell)\n      throw new Fail(`No shell is available: ${Fail.DOCS_URL}/shell`)\n    if (!$.quote)\n      throw new Fail(`No quote function is defined: ${Fail.DOCS_URL}/quotes`)\n    if ($.pieces.some((p) => p == null))\n      throw new Fail(`Malformed command at ${$.from}`)\n\n    $.cmd = buildCmd(\n      $.quote!,\n      $.pieces as TemplateStringsArray,\n      $.args\n    ) as string\n\n    if ($[SYNC] && !isString($.cmd))\n      throw new Fail('sync mode does not allow async command resolution')\n  }\n  run(): this {\n    ProcessPromise.bus.runBack(this)\n    if (this.isRunning() || this.isSettled()) return this // The _run() can be called from a few places.\n    this._stage = 'running'\n\n    const self = this","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/google/zx/blob/00a2c484e219c2e84bfc3a199febf7fbce2cfbf4/src/core.ts#L278-L314","documentation":"Thrown by ProcessPromise.build() when $.quote is undefined. zx needs a shell-specific quoting function to safely interpolate arguments; quote is normally assigned by useBash()/usePwsh()/usePowerShell(). At module load zx calls useBash(); if bash is not found, which.sync throws and the assignment is skipped inside an empty try/catch, leaving $.quote undefined, so the very first `$` call hits this guard. See /quotes.","triggerScenarios":"Running zx on a system without bash (Alpine, distroless, minimal containers) with no other shell configured; setting $.shell to a custom path without also providing $.quote; overriding Options in a way that drops the quote key.","commonSituations":"Docker `alpine`/scratch images without bash; CI on a minimal image; custom shells (fish, sh, busybox) set via $.shell but with no matching quote function; Node runtimes where bash is not on PATH.","solutions":["Install bash in the environment (`apk add bash`, `apt-get install -y bash`).","Switch to a configured shell helper: `usePwsh()` or `usePowerShell()`.","Provide both shell and quote explicitly: `$.shell = '/bin/sh'; $.quote = quote` (import the built-in `quote` for POSIX shells).","Set `$.shell = true` and ensure bash exists so auto-detection works."],"exampleFix":"// Dockerfile before\nFROM alpine\nRUN npm i -g zx\n// after: install bash so useBash() succeeds and $.quote gets set\nFROM alpine\nRUN apk add --no-cache bash && npm i -g zx","handlingStrategy":"validation","validationCode":"import { $, quote } from 'zx'\n\nfunction ensureQuoteFn(): void {\n  if (typeof $.quote !== 'function') {\n    // POSIX fallback when bash is absent\n    $.shell = $.shell || '/bin/sh'\n    $.quote = quote\n  }\n}\n\nensureQuoteFn()","typeGuard":"const hasQuoteFn = (v: unknown): v is (s: string) => string =>\n  typeof v === 'function'","tryCatchPattern":"import { Fail, quote } from 'zx'\ntry {\n  await $`echo hi`\n} catch (e) {\n  if (e instanceof Fail && /No quote function is defined/.test(e.message)) {\n    $.quote = quote\n    await $`echo hi`\n  } else throw e\n}","preventionTips":["Install bash in minimal Docker images (apk add bash / apt-get install -y bash).","When setting a custom $.shell, always pair it with a matching $.quote (use built-in quote for POSIX shells).","Prefer useBash()/usePwsh()/usePowerShell() helpers over manual shell assignment."],"tags":["shell","quotes","environment","docker","alpine"],"backgroundTag":null,"analyzedSha":"00a2c484e219c2e84bfc3a199febf7fbce2cfbf4","analyzedAt":"2026-08-13T02:11:06.305Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}