Hmbown/CodeWhale · error · Error
fn + "(): unknown mode " + JSON.stringify(opts.mode) + "…
Error message
fn + "(): unknown mode " + JSON.stringify(opts.mode) + "; expected one of " + SLOT_MODES.join(", ") What it means
slotMode() validates the opts.mode given to parallel()/pipeline() against the allowed SLOT_MODES. An options object with a mode outside that set throws this error naming the function, the bad mode, and the valid modes. Missing mode or a non-object opts defaults to "settled" without error.
Solutions
- Use exactly one of the listed modes; per the code paths these are 'settled', 'fail-fast', and 'partial'.
- Fix casing/spelling: 'fail-fast' is hyphenated and lowercase.
- Omit the mode option entirely to get the default 'settled' behavior.
- Log JSON.stringify(opts.mode) at the call site to see the actual value being passed.
Example fix
// before
await parallel(thunks, { mode: 'failfast' });
// after
await parallel(thunks, { mode: 'fail-fast' }); Defensive patterns
Strategy: validation
Validate before calling
const SLOT_MODES = ['settled', 'fail-fast', 'partial'];
function validSlotMode(opts) {
return opts == null || typeof opts !== 'object' || opts.mode === undefined
|| SLOT_MODES.includes(opts.mode);
} Type guard
const isSlotOpts = (o) => o == null || (typeof o === 'object' && (o.mode === undefined || ['settled','fail-fast','partial'].includes(o.mode)));
Try / catch
try {
await parallel(thunks, opts);
} catch (e) {
if (e.message.includes('unknown mode')) {
await parallel(thunks); // fall back to default 'settled'
} else throw e;
} Prevention
- Use the exact literal mode strings: 'settled', 'fail-fast', 'partial'
- Omit mode when you want the default settled behavior
- Centralize slot option construction in one helper
When it happens
Trigger: Calling parallel(thunks, { mode: '...' }) or pipeline(items, { mode: '...' }) with a mode string not in SLOT_MODES (e.g. 'abort', 'failfast', 'Fail-Fast', or a non-string value like true or 1).
Common situations: Typos ('failfast' vs 'fail-fast'), assuming other modes exist, casing mistakes, or passing a boolean where the mode string was expected.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- (): unknown mode ; expected one of
- 1
- A pinned task provider requires an explicit model
- A positive pull request number is required
- A provider and page loader are required.
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/1ef3c77f9758ccac.
Report an issue: GitHub.
Appendix: source
Thrown at crates/workflow-js/src/vm.rs:1333
} catch (_) {
// A frozen error keeps whatever it has; the log line still names it.
}
}
return err;
};
const SLOT_MODES = ["settled", "fail-fast", "partial"];
// `settled` is the default and is exactly today's behavior: a non-fatal
// slot failure resolves to `null` so an author need not handle every error.
// An unrecognized mode throws rather than silently falling back — a typo
// like `mode: "failfast"` used to read as `settled` and quietly keep
// dropping slots the author believed were now fatal.
const slotMode = (fn, opts) => {
if (opts === null || typeof opts !== "object" || opts.mode === undefined) {
return "settled";
}
if (SLOT_MODES.indexOf(opts.mode) === -1) {
throw new Error(
fn + "(): unknown mode " + JSON.stringify(opts.mode) +
"; expected one of " + SLOT_MODES.join(", ")
);
}
return opts.mode;
};
// The failure ledger for one fan-out, attached to the resolved array as a
// non-enumerable `errors` property. Non-enumerable and non-index, so the
// array's contents, length, and JSON encoding are byte-identical to before:
// `results.filter(Boolean)` still works, and a script that wants to know
// WHY a slot is null can now ask instead of guessing.
const attachSlotErrors = (results, errors) => {
errors.sort((a, b) => a.index - b.index);
Object.defineProperty(results, "errors", {
value: Object.freeze(errors.map((entry) => Object.freeze(entry))),
enumerable: false,
configurable: false,View on GitHub (pinned to 433685b202)