denoland/deno · error · Error
'create' or 'createNew' options require 'write' or 'append'…
Error message
'create' or 'createNew' options require 'write' or 'append' to be true
What it means
create and createNew make Deno.open create the file, which only makes sense on a writable or appendable handle. Opening with create flags but no write/append would create a file you could not write to, so Deno rejects the combination before touching the filesystem.
Solutions
- Add write: true (or append: true) whenever create/createNew is used
- For create-and-write semantics use the shorthand Deno.create(path) (read+write+create+truncate)
- For touch-like behavior, Deno.createSync(path) then immediately close
Example fix
// before
const f = await Deno.open(path, { create: true });
// after
const f = await Deno.open(path, { read: true, write: true, create: true }); Defensive patterns
Strategy: validation
Validate before calling
function normalizeOpenOptions(o) {
if ((o.create || o.createNew) && !(o.write || o.append)) {
o = { ...o, write: true };
}
return o;
}
const f = await Deno.open(path, normalizeOpenOptions(opts)); Prevention
- Treat create/createNew as write-intent flags and always add write or append
- Prefer the Deno.create() shorthand for create-and-write
- Do not use open-with-create as an 'ensure exists' probe
When it happens
Trigger: Deno.open(path, { create: true }); Deno.open(path, { createNew: true, read: true }) with no write/append; 'ensure the file exists' logic implemented as open-with-create.
Common situations: Touch-like existence checks; porting Node fs.open mappings; copy-pasted option objects where the write line was dropped.
Related errors
- 'options' requires at least one option to be true
- 'truncate' option requires 'write' to be true
- A file exists at the destination
- ABORT_ERR
- Cannot construct UnsafeCallback: cannot be nonblocking
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/745f9e7c17dad73e.
Report an issue: GitHub.
Appendix: source
Thrown at ext/fs/30_fs.js:817
).length === 0
) {
throw new Error(
"'options' requires at least one option to be true",
);
}
if (options.truncate && !options.write) {
throw new Error(
"'truncate' option requires 'write' to be true",
);
}
const createOrCreateNewWithoutWriteOrAppend =
(options.create || options.createNew) &&
!(options.write || options.append);
if (createOrCreateNewWithoutWriteOrAppend) {
throw new Error(
"'create' or 'createNew' options require 'write' or 'append' to be true",
);
}
}
function readFileSync(path) {
return op_fs_read_file_sync(pathFromURL(path));
}
async function readFile(path, options) {
let cancelRid;
let abortHandler;
if (options?.signal) {
options.signal.throwIfAborted();
cancelRid = createCancelHandle();
abortHandler = () => core.tryClose(cancelRid);
options.signal[abortSignal.add](abortHandler);
}View on GitHub (pinned to 9ad36f7a2c)