{"record":{"id":"745f9e7c17dad73e","repo":"denoland/deno","slug":"create-or-createnew-options-require-write-or","errorCode":null,"errorMessage":"'create' or 'createNew' options require 'write' or 'append' to be true","messagePattern":"'create' or 'createNew' options require 'write' or 'append' to be true","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/fs/30_fs.js","lineNumber":817,"sourceCode":"    ).length === 0\n  ) {\n    throw new Error(\n      \"'options' requires at least one option to be true\",\n    );\n  }\n\n  if (options.truncate && !options.write) {\n    throw new Error(\n      \"'truncate' option requires 'write' to be true\",\n    );\n  }\n\n  const createOrCreateNewWithoutWriteOrAppend =\n    (options.create || options.createNew) &&\n    !(options.write || options.append);\n\n  if (createOrCreateNewWithoutWriteOrAppend) {\n    throw new Error(\n      \"'create' or 'createNew' options require 'write' or 'append' to be true\",\n    );\n  }\n}\n\nfunction readFileSync(path) {\n  return op_fs_read_file_sync(pathFromURL(path));\n}\n\nasync function readFile(path, options) {\n  let cancelRid;\n  let abortHandler;\n  if (options?.signal) {\n    options.signal.throwIfAborted();\n    cancelRid = createCancelHandle();\n    abortHandler = () => core.tryClose(cancelRid);\n    options.signal[abortSignal.add](abortHandler);\n  }","sourceCodeStart":799,"sourceCodeEnd":835,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/fs/30_fs.js#L799-L835","documentation":"Final rule of checkOpenOptions for Deno.open/openSync: create/createNew only make sense when the file will also be written or appended to. Opening with create: true (or createNew: true) but neither write nor append would create a file that can never receive bytes, so a plain Error is thrown. This mirrors Node's validation for the same flag combinations.","triggerScenarios":"Deno.open(path, { create: true }) or Deno.openSync(path, { createNew: true }) without write: true or append: true.","commonSituations":"Expecting create to work like touch; porting Node flag 'wx'/'ax' partially; constructing options from conditionals where the write flag is dropped when a file already exists.","solutions":["Pair create with write: { create: true, write: true } (or append: true)","For touch-like creation with content, use Deno.writeTextFile with create: true","For Node-'w' behavior use { write: true, create: true, truncate: true }; for fail-if-exists use createNew"],"exampleFix":"// before\nawait Deno.open(\"/tmp/x\", { create: true }); // Error\n\n// after\nawait Deno.open(\"/tmp/x\", { create: true, write: true });","handlingStrategy":"validation","validationCode":"function normalizeOpenOptions(o) {\n  if ((o.create || o.createNew) && !(o.write || o.append)) o = { ...o, write: true };\n  return o;\n}\nawait Deno.open(path, normalizeOpenOptions(options));","typeGuard":"function areCreateOptionsValid(o: {\n  create?: boolean;\n  createNew?: boolean;\n  write?: boolean;\n  append?: boolean;\n}): boolean {\n  return !((o.create || o.createNew) && !(o.write || o.append));\n}","tryCatchPattern":"try {\n  file = await Deno.open(path, options);\n} catch (err) {\n  if (err instanceof Error && err.message === \"'create' or 'createNew' options require 'write' or 'append' to be true\") {\n    file = await Deno.open(path, { ...options, write: true });\n  } else throw err;\n}","preventionTips":["Remember create/createNew alone do nothing valid; add write or append","For touch-like creation use Deno.writeTextFile(path, \"\", { create: true })","Centralize flag mapping from other runtimes instead of hand-building options per call"],"tags":["fs","open","create","options"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}